ConfigurationClassPostProcessor programmatically registers unified ImportAwareBeanPostProcessor
Issue: SPR-14931
This commit is contained in:
parent
30df137273
commit
f6b2a21206
|
|
@ -151,7 +151,6 @@ class ConfigurationClassEnhancer {
|
||||||
* must remain public in order to allow access to subclasses generated from other
|
* must remain public in order to allow access to subclasses generated from other
|
||||||
* packages (i.e. user code).
|
* packages (i.e. user code).
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
|
||||||
public interface EnhancedConfiguration extends BeanFactoryAware {
|
public interface EnhancedConfiguration extends BeanFactoryAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +159,6 @@ class ConfigurationClassEnhancer {
|
||||||
* Conditional {@link Callback}.
|
* Conditional {@link Callback}.
|
||||||
* @see ConditionalCallbackFilter
|
* @see ConditionalCallbackFilter
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
|
||||||
private interface ConditionalCallback extends Callback {
|
private interface ConditionalCallback extends Callback {
|
||||||
|
|
||||||
boolean isMatch(Method candidateMethod);
|
boolean isMatch(Method candidateMethod);
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,9 @@ import org.springframework.beans.PropertyValues;
|
||||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
|
||||||
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
|
||||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||||
|
|
@ -53,7 +50,6 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
|
||||||
import org.springframework.context.EnvironmentAware;
|
import org.springframework.context.EnvironmentAware;
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration;
|
import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration;
|
||||||
|
|
@ -91,15 +87,9 @@ import static org.springframework.context.annotation.AnnotationConfigUtils.*;
|
||||||
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
|
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
|
||||||
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
|
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
|
||||||
|
|
||||||
private static final String IMPORT_AWARE_PROCESSOR_BEAN_NAME =
|
|
||||||
ConfigurationClassPostProcessor.class.getName() + ".importAwareProcessor";
|
|
||||||
|
|
||||||
private static final String IMPORT_REGISTRY_BEAN_NAME =
|
private static final String IMPORT_REGISTRY_BEAN_NAME =
|
||||||
ConfigurationClassPostProcessor.class.getName() + ".importRegistry";
|
ConfigurationClassPostProcessor.class.getName() + ".importRegistry";
|
||||||
|
|
||||||
private static final String ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME =
|
|
||||||
ConfigurationClassPostProcessor.class.getName() + ".enhancedConfigurationProcessor";
|
|
||||||
|
|
||||||
|
|
||||||
private final Log logger = LogFactory.getLog(getClass());
|
private final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
|
|
@ -224,14 +214,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
|
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
|
||||||
RootBeanDefinition iabpp = new RootBeanDefinition(ImportAwareBeanPostProcessor.class);
|
|
||||||
iabpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
|
||||||
registry.registerBeanDefinition(IMPORT_AWARE_PROCESSOR_BEAN_NAME, iabpp);
|
|
||||||
|
|
||||||
RootBeanDefinition ecbpp = new RootBeanDefinition(EnhancedConfigurationBeanPostProcessor.class);
|
|
||||||
ecbpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
|
||||||
registry.registerBeanDefinition(ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME, ecbpp);
|
|
||||||
|
|
||||||
int registryId = System.identityHashCode(registry);
|
int registryId = System.identityHashCode(registry);
|
||||||
if (this.registriesPostProcessed.contains(registryId)) {
|
if (this.registriesPostProcessed.contains(registryId)) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
|
|
@ -263,7 +245,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
// Simply call processConfigurationClasses lazily at this point then.
|
// Simply call processConfigurationClasses lazily at this point then.
|
||||||
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
|
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
enhanceConfigurationClasses(beanFactory);
|
enhanceConfigurationClasses(beanFactory);
|
||||||
|
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -422,18 +406,22 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class ImportAwareBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware, PriorityOrdered {
|
private static class ImportAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
|
||||||
|
|
||||||
private BeanFactory beanFactory;
|
private final BeanFactory beanFactory;
|
||||||
|
|
||||||
@Override
|
public ImportAwareBeanPostProcessor(BeanFactory beanFactory) {
|
||||||
public void setBeanFactory(BeanFactory beanFactory) {
|
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||||
return Ordered.HIGHEST_PRECEDENCE;
|
// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
|
||||||
|
// postProcessPropertyValues method attempts to autowire other configuration beans.
|
||||||
|
if (bean instanceof EnhancedConfiguration) {
|
||||||
|
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
|
||||||
|
}
|
||||||
|
return pvs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -454,36 +442,4 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link InstantiationAwareBeanPostProcessorAdapter} that ensures
|
|
||||||
* {@link EnhancedConfiguration} beans are injected with the {@link BeanFactory}
|
|
||||||
* before the {@link AutowiredAnnotationBeanPostProcessor} runs (SPR-10668).
|
|
||||||
*/
|
|
||||||
private static class EnhancedConfigurationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
|
|
||||||
implements PriorityOrdered, BeanFactoryAware {
|
|
||||||
|
|
||||||
private BeanFactory beanFactory;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return Ordered.HIGHEST_PRECEDENCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBeanFactory(BeanFactory beanFactory) {
|
|
||||||
this.beanFactory = beanFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
|
||||||
// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
|
|
||||||
// postProcessPropertyValues method attempts to auto-wire other configuration beans.
|
|
||||||
if (bean instanceof EnhancedConfiguration) {
|
|
||||||
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
|
|
||||||
}
|
|
||||||
return pvs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -38,29 +38,20 @@ public class Spr10668Tests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelfInjectHierarchy() throws Exception {
|
public void testSelfInjectHierarchy() throws Exception {
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ChildConfig.class);
|
||||||
ChildConfig.class);
|
|
||||||
assertNotNull(context.getBean(MyComponent.class));
|
assertNotNull(context.getBean(MyComponent.class));
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class ParentConfig implements BeanFactoryAware {
|
public static class ParentConfig {
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
MyComponent component;
|
MyComponent component;
|
||||||
|
|
||||||
public ParentConfig() {
|
|
||||||
System.out.println("Parent " + getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
|
||||||
System.out.println("BFA " + getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class ChildConfig extends ParentConfig {
|
public static class ChildConfig extends ParentConfig {
|
||||||
|
|
||||||
|
|
@ -68,12 +59,11 @@ public class Spr10668Tests {
|
||||||
public MyComponentImpl myComponent() {
|
public MyComponentImpl myComponent() {
|
||||||
return new MyComponentImpl();
|
return new MyComponentImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface MyComponent {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MyComponentImpl implements MyComponent {
|
public interface MyComponent {}
|
||||||
}
|
|
||||||
|
public static class MyComponentImpl implements MyComponent {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue