Support ConfigurationClassPostProcessor supplier

Update `SharedMetadataReaderFactoryContextInitializer` to optionally
support a `ConfigurationClassPostProcessor` provided via an instance
`Supplier`.

If the instance supplier is available then we can use that to set the
`MetadataReaderFactory` non-reflectively, instead of using a
`PropertyValue` (and the `BeanWrapper` eventually).

The previous behavior is left as a  fallback and without a change in
Spring Framework will continue to be the default for most applications.

See gh-22858
This commit is contained in:
Dave Syer 2020-08-11 12:11:57 +01:00 committed by Phillip Webb
parent 4799b26d2c
commit 06eff45a71
1 changed files with 26 additions and 1 deletions

View File

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure;
import java.util.function.Supplier;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
@ -23,6 +25,7 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
@ -53,7 +56,7 @@ class SharedMetadataReaderFactoryContextInitializer
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.addBeanFactoryPostProcessor(new CachingMetadataReaderFactoryPostProcessor());
applicationContext.addBeanFactoryPostProcessor(new CachingMetadataReaderFactoryPostProcessor(applicationContext));
}
@Override
@ -69,6 +72,12 @@ class SharedMetadataReaderFactoryContextInitializer
private static class CachingMetadataReaderFactoryPostProcessor
implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
private ConfigurableApplicationContext context;
CachingMetadataReaderFactoryPostProcessor(ConfigurableApplicationContext context) {
this.context = context;
}
@Override
public int getOrder() {
// Must happen before the ConfigurationClassPostProcessor is created
@ -96,12 +105,28 @@ class SharedMetadataReaderFactoryContextInitializer
try {
BeanDefinition definition = registry
.getBeanDefinition(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME);
if (definition instanceof AbstractBeanDefinition) {
AbstractBeanDefinition bean = (AbstractBeanDefinition) definition;
if (bean.getInstanceSupplier() != null) {
Supplier<?> supplier = bean.getInstanceSupplier();
bean.setInstanceSupplier(() -> modify(supplier));
return;
}
}
definition.getPropertyValues().add("metadataReaderFactory", new RuntimeBeanReference(BEAN_NAME));
}
catch (NoSuchBeanDefinitionException ex) {
}
}
private Object modify(Supplier<?> supplier) {
Object object = supplier.get();
if (object instanceof ConfigurationClassPostProcessor) {
((ConfigurationClassPostProcessor) object).setMetadataReaderFactory(this.context.getBean(BEAN_NAME, MetadataReaderFactory.class));
}
return object;
}
}
/**