|
16 | 16 |
|
17 | 17 | package org.springframework.context.annotation; |
18 | 18 |
|
| 19 | +import java.beans.PropertyDescriptor; |
19 | 20 | import java.io.IOException; |
20 | 21 | import java.util.HashSet; |
21 | 22 | import java.util.LinkedHashMap; |
|
27 | 28 | import org.apache.commons.logging.Log; |
28 | 29 | import org.apache.commons.logging.LogFactory; |
29 | 30 | import org.springframework.beans.BeansException; |
| 31 | +import org.springframework.beans.PropertyValues; |
30 | 32 | import org.springframework.beans.factory.BeanClassLoaderAware; |
31 | 33 | import org.springframework.beans.factory.BeanDefinitionStoreException; |
32 | 34 | import org.springframework.beans.factory.BeanFactory; |
33 | 35 | import org.springframework.beans.factory.BeanFactoryAware; |
| 36 | +import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; |
34 | 37 | import org.springframework.beans.factory.config.BeanDefinition; |
35 | 38 | import org.springframework.beans.factory.config.BeanDefinitionHolder; |
36 | 39 | import org.springframework.beans.factory.config.BeanFactoryPostProcessor; |
37 | 40 | import org.springframework.beans.factory.config.BeanPostProcessor; |
38 | 41 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
| 42 | +import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; |
39 | 43 | import org.springframework.beans.factory.config.SingletonBeanRegistry; |
40 | 44 | import org.springframework.beans.factory.parsing.FailFastProblemReporter; |
41 | 45 | import org.springframework.beans.factory.parsing.PassThroughSourceExtractor; |
|
50 | 54 | import org.springframework.context.ApplicationContextAware; |
51 | 55 | import org.springframework.context.EnvironmentAware; |
52 | 56 | import org.springframework.context.ResourceLoaderAware; |
| 57 | +import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration; |
53 | 58 | import org.springframework.context.annotation.ConfigurationClassParser.ImportRegistry; |
54 | 59 | import org.springframework.core.Ordered; |
55 | 60 | import org.springframework.core.PriorityOrdered; |
@@ -96,6 +101,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo |
96 | 101 | private static final String IMPORT_REGISTRY_BEAN_NAME = |
97 | 102 | ConfigurationClassPostProcessor.class.getName() + ".importRegistry"; |
98 | 103 |
|
| 104 | + private static final String ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME = |
| 105 | + ConfigurationClassPostProcessor.class.getName() + ".enhancedConfigurationProcessor"; |
| 106 | + |
99 | 107 |
|
100 | 108 | private final Log logger = LogFactory.getLog(getClass()); |
101 | 109 |
|
@@ -225,6 +233,10 @@ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { |
225 | 233 | iabpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); |
226 | 234 | registry.registerBeanDefinition(IMPORT_AWARE_PROCESSOR_BEAN_NAME, iabpp); |
227 | 235 |
|
| 236 | + RootBeanDefinition ecbpp = new RootBeanDefinition(EnhancedConfigurationBeanPostProcessor.class); |
| 237 | + ecbpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); |
| 238 | + registry.registerBeanDefinition(ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME, ecbpp); |
| 239 | + |
228 | 240 | int registryId = System.identityHashCode(registry); |
229 | 241 | if (this.registriesPostProcessed.contains(registryId)) { |
230 | 242 | throw new IllegalStateException( |
@@ -424,4 +436,40 @@ public int getOrder() { |
424 | 436 | } |
425 | 437 | } |
426 | 438 |
|
| 439 | + |
| 440 | + /** |
| 441 | + * {@link InstantiationAwareBeanPostProcessorAdapter} that ensures |
| 442 | + * {@link EnhancedConfiguration} beans are injected with the {@link BeanFactory} |
| 443 | + * before the {@link AutowiredAnnotationBeanPostProcessor} runs (SPR-10668). |
| 444 | + */ |
| 445 | + private static class EnhancedConfigurationBeanPostProcessor extends |
| 446 | + InstantiationAwareBeanPostProcessorAdapter implements PriorityOrdered, |
| 447 | + BeanFactoryAware { |
| 448 | + |
| 449 | + private BeanFactory beanFactory; |
| 450 | + |
| 451 | + @Override |
| 452 | + public int getOrder() { |
| 453 | + return Ordered.HIGHEST_PRECEDENCE; |
| 454 | + } |
| 455 | + |
| 456 | + @Override |
| 457 | + public PropertyValues postProcessPropertyValues(PropertyValues pvs, |
| 458 | + PropertyDescriptor[] pds, Object bean, String beanName) |
| 459 | + throws BeansException { |
| 460 | + // Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's |
| 461 | + // postProcessPropertyValues method attempts to auto-wire other configuration |
| 462 | + // beans. |
| 463 | + if (bean instanceof EnhancedConfiguration) { |
| 464 | + ((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory); |
| 465 | + } |
| 466 | + return pvs; |
| 467 | + } |
| 468 | + |
| 469 | + @Override |
| 470 | + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
| 471 | + this.beanFactory = beanFactory; |
| 472 | + } |
| 473 | + |
| 474 | + } |
427 | 475 | } |
0 commit comments