|
|
|
|
@ -66,6 +66,7 @@ import org.springframework.core.type.StandardAnnotationMetadata;
@@ -66,6 +66,7 @@ import org.springframework.core.type.StandardAnnotationMetadata;
|
|
|
|
|
import org.springframework.core.type.classreading.MetadataReader; |
|
|
|
|
import org.springframework.core.type.classreading.MetadataReaderFactory; |
|
|
|
|
import org.springframework.core.type.filter.AssignableTypeFilter; |
|
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
import org.springframework.util.LinkedMultiValueMap; |
|
|
|
|
import org.springframework.util.MultiValueMap; |
|
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
@ -315,9 +316,7 @@ class ConfigurationClassParser {
@@ -315,9 +316,7 @@ class ConfigurationClassParser {
|
|
|
|
|
String name = propertySource.getString("name"); |
|
|
|
|
String[] locations = propertySource.getStringArray("value"); |
|
|
|
|
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound"); |
|
|
|
|
if (locations.length == 0) { |
|
|
|
|
throw new IllegalArgumentException("At least one @PropertySource(value) location is required"); |
|
|
|
|
} |
|
|
|
|
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required"); |
|
|
|
|
for (String location : locations) { |
|
|
|
|
try { |
|
|
|
|
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location); |
|
|
|
|
@ -401,6 +400,7 @@ class ConfigurationClassParser {
@@ -401,6 +400,7 @@ class ConfigurationClassParser {
|
|
|
|
|
if (importCandidates.isEmpty()) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (checkForCircularImports && this.importStack.contains(configClass)) { |
|
|
|
|
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata())); |
|
|
|
|
} |
|
|
|
|
@ -409,12 +409,13 @@ class ConfigurationClassParser {
@@ -409,12 +409,13 @@ class ConfigurationClassParser {
|
|
|
|
|
try { |
|
|
|
|
for (SourceClass candidate : importCandidates) { |
|
|
|
|
if (candidate.isAssignable(ImportSelector.class)) { |
|
|
|
|
// the candidate class is an ImportSelector -> delegate to it to determine imports
|
|
|
|
|
// Candidate class is an ImportSelector -> delegate to it to determine imports
|
|
|
|
|
Class<?> candidateClass = candidate.loadClass(); |
|
|
|
|
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); |
|
|
|
|
invokeAwareMethods(selector); |
|
|
|
|
if (selector instanceof DeferredImportSelector) { |
|
|
|
|
this.deferredImportSelectors.add(new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); |
|
|
|
|
this.deferredImportSelectors.add( |
|
|
|
|
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); |
|
|
|
|
@ -423,15 +424,19 @@ class ConfigurationClassParser {
@@ -423,15 +424,19 @@ class ConfigurationClassParser {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { |
|
|
|
|
// the candidate class is an ImportBeanDefinitionRegistrar -> delegate to it to register additional bean definitions
|
|
|
|
|
// Candidate class is an ImportBeanDefinitionRegistrar ->
|
|
|
|
|
// delegate to it to register additional bean definitions
|
|
|
|
|
Class<?> candidateClass = candidate.loadClass(); |
|
|
|
|
ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); |
|
|
|
|
ImportBeanDefinitionRegistrar registrar = |
|
|
|
|
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); |
|
|
|
|
invokeAwareMethods(registrar); |
|
|
|
|
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
// candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> process it as a @Configuration class
|
|
|
|
|
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); |
|
|
|
|
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
|
|
|
|
|
// process it as a @Configuration class
|
|
|
|
|
this.importStack.registerImport( |
|
|
|
|
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); |
|
|
|
|
processConfigurationClass(candidate.asConfigClass(configClass)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -645,12 +650,12 @@ class ConfigurationClassParser {
@@ -645,12 +650,12 @@ class ConfigurationClassParser {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Simple wrapper that allows annotated source classes to be dealt with in a uniform |
|
|
|
|
* manor, regardless of how they are loaded. |
|
|
|
|
* Simple wrapper that allows annotated source classes to be dealt with |
|
|
|
|
* in a uniform manner, regardless of how they are loaded. |
|
|
|
|
*/ |
|
|
|
|
private class SourceClass { |
|
|
|
|
|
|
|
|
|
private final Object source; // Class or MetaDataReader
|
|
|
|
|
private final Object source; // Class or MetadataReader
|
|
|
|
|
|
|
|
|
|
private final AnnotationMetadata metadata; |
|
|
|
|
|
|
|
|
|
|