|
17 | 17 | package org.springframework.context.annotation;
|
18 | 18 |
|
19 | 19 | import java.beans.PropertyDescriptor;
|
| 20 | +import java.util.Arrays; |
20 | 21 | import java.util.HashSet;
|
21 | 22 | import java.util.LinkedHashMap;
|
22 | 23 | import java.util.LinkedHashSet;
|
@@ -269,7 +270,9 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
269 | 270 | */
|
270 | 271 | public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
|
271 | 272 | Set<BeanDefinitionHolder> configCandidates = new LinkedHashSet<BeanDefinitionHolder>();
|
272 |
| - for (String beanName : registry.getBeanDefinitionNames()) { |
| 273 | + String[] candidateNames = registry.getBeanDefinitionNames(); |
| 274 | + |
| 275 | + for (String beanName : candidateNames) { |
273 | 276 | BeanDefinition beanDef = registry.getBeanDefinition(beanName);
|
274 | 277 | if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
|
275 | 278 | ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
|
@@ -302,32 +305,59 @@ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.
|
302 | 305 | ConfigurationClassParser parser = new ConfigurationClassParser(
|
303 | 306 | this.metadataReaderFactory, this.problemReporter, this.environment,
|
304 | 307 | this.resourceLoader, this.componentScanBeanNameGenerator, registry);
|
305 |
| - parser.parse(configCandidates); |
306 |
| - parser.validate(); |
307 |
| - |
308 |
| - // Handle any @PropertySource annotations |
309 |
| - List<PropertySource<?>> parsedPropertySources = parser.getPropertySources(); |
310 |
| - if (!parsedPropertySources.isEmpty()) { |
311 |
| - if (!(this.environment instanceof ConfigurableEnvironment)) { |
312 |
| - logger.warn("Ignoring @PropertySource annotations. " + |
313 |
| - "Reason: Environment must implement ConfigurableEnvironment"); |
314 |
| - } |
315 |
| - else { |
316 |
| - MutablePropertySources envPropertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); |
317 |
| - for (PropertySource<?> propertySource : parsedPropertySources) { |
318 |
| - envPropertySources.addLast(propertySource); |
| 308 | + |
| 309 | + Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size()); |
| 310 | + int propertySourceCount = 0; |
| 311 | + do { |
| 312 | + parser.parse(configCandidates); |
| 313 | + parser.validate(); |
| 314 | + |
| 315 | + // Handle any @PropertySource annotations |
| 316 | + if (parser.getPropertySourceCount() > propertySourceCount) { |
| 317 | + List<PropertySource<?>> parsedPropertySources = parser.getPropertySources(); |
| 318 | + if (!parsedPropertySources.isEmpty()) { |
| 319 | + if (!(this.environment instanceof ConfigurableEnvironment)) { |
| 320 | + logger.warn("Ignoring @PropertySource annotations. " + |
| 321 | + "Reason: Environment must implement ConfigurableEnvironment"); |
| 322 | + } |
| 323 | + else { |
| 324 | + MutablePropertySources envPropertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); |
| 325 | + for (PropertySource<?> propertySource : parsedPropertySources) { |
| 326 | + envPropertySources.addLast(propertySource); |
| 327 | + } |
| 328 | + } |
319 | 329 | }
|
| 330 | + propertySourceCount = parser.getPropertySourceCount(); |
320 | 331 | }
|
321 |
| - } |
322 | 332 |
|
323 |
| - // Read the model and create bean definitions based on its content |
324 |
| - if (this.reader == null) { |
325 |
| - this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, |
326 |
| - this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment, |
327 |
| - this.importBeanNameGenerator); |
328 |
| - } |
| 333 | + Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses()); |
| 334 | + configClasses.removeAll(alreadyParsed); |
329 | 335 |
|
330 |
| - this.reader.loadBeanDefinitions(parser.getConfigurationClasses()); |
| 336 | + // Read the model and create bean definitions based on its content |
| 337 | + if (this.reader == null) { |
| 338 | + this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, |
| 339 | + this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment, |
| 340 | + this.importBeanNameGenerator); |
| 341 | + } |
| 342 | + this.reader.loadBeanDefinitions(configClasses); |
| 343 | + alreadyParsed.addAll(configClasses); |
| 344 | + |
| 345 | + configCandidates.clear(); |
| 346 | + if (registry.getBeanDefinitionCount() > candidateNames.length) { |
| 347 | + String[] newCandidateNames = registry.getBeanDefinitionNames(); |
| 348 | + Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames)); |
| 349 | + for (String candidateName : newCandidateNames) { |
| 350 | + if (!oldCandidateNames.contains(candidateName)) { |
| 351 | + BeanDefinition beanDef = registry.getBeanDefinition(candidateName); |
| 352 | + if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { |
| 353 | + configCandidates.add(new BeanDefinitionHolder(beanDef, candidateName)); |
| 354 | + } |
| 355 | + } |
| 356 | + } |
| 357 | + candidateNames = newCandidateNames; |
| 358 | + } |
| 359 | + } |
| 360 | + while (!configCandidates.isEmpty()); |
331 | 361 |
|
332 | 362 | // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
|
333 | 363 | if (singletonRegistry != null) {
|
|
0 commit comments