Revised test for ImportBeanDefinitionRegistrar double scan
Issue: SPR-12334
This commit is contained in:
parent
15c8987cc4
commit
6e5711a7fb
|
@ -66,6 +66,7 @@ import org.springframework.core.type.StandardAnnotationMetadata;
|
||||||
import org.springframework.core.type.classreading.MetadataReader;
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
@ -315,9 +316,7 @@ class ConfigurationClassParser {
|
||||||
String name = propertySource.getString("name");
|
String name = propertySource.getString("name");
|
||||||
String[] locations = propertySource.getStringArray("value");
|
String[] locations = propertySource.getStringArray("value");
|
||||||
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
|
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
|
||||||
if (locations.length == 0) {
|
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
|
||||||
throw new IllegalArgumentException("At least one @PropertySource(value) location is required");
|
|
||||||
}
|
|
||||||
for (String location : locations) {
|
for (String location : locations) {
|
||||||
try {
|
try {
|
||||||
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
|
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
|
||||||
|
@ -401,6 +400,7 @@ class ConfigurationClassParser {
|
||||||
if (importCandidates.isEmpty()) {
|
if (importCandidates.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkForCircularImports && this.importStack.contains(configClass)) {
|
if (checkForCircularImports && this.importStack.contains(configClass)) {
|
||||||
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata()));
|
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata()));
|
||||||
}
|
}
|
||||||
|
@ -409,12 +409,13 @@ class ConfigurationClassParser {
|
||||||
try {
|
try {
|
||||||
for (SourceClass candidate : importCandidates) {
|
for (SourceClass candidate : importCandidates) {
|
||||||
if (candidate.isAssignable(ImportSelector.class)) {
|
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();
|
Class<?> candidateClass = candidate.loadClass();
|
||||||
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
|
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
|
||||||
invokeAwareMethods(selector);
|
invokeAwareMethods(selector);
|
||||||
if (selector instanceof DeferredImportSelector) {
|
if (selector instanceof DeferredImportSelector) {
|
||||||
this.deferredImportSelectors.add(new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
|
this.deferredImportSelectors.add(
|
||||||
|
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
|
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
|
||||||
|
@ -423,15 +424,19 @@ class ConfigurationClassParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
|
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();
|
Class<?> candidateClass = candidate.loadClass();
|
||||||
ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
|
ImportBeanDefinitionRegistrar registrar =
|
||||||
|
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
|
||||||
invokeAwareMethods(registrar);
|
invokeAwareMethods(registrar);
|
||||||
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
|
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> process it as a @Configuration class
|
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
|
||||||
this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
|
// process it as a @Configuration class
|
||||||
|
this.importStack.registerImport(
|
||||||
|
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
|
||||||
processConfigurationClass(candidate.asConfigClass(configClass));
|
processConfigurationClass(candidate.asConfigClass(configClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -645,12 +650,12 @@ class ConfigurationClassParser {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper that allows annotated source classes to be dealt with in a uniform
|
* Simple wrapper that allows annotated source classes to be dealt with
|
||||||
* manor, regardless of how they are loaded.
|
* in a uniform manner, regardless of how they are loaded.
|
||||||
*/
|
*/
|
||||||
private class SourceClass {
|
private class SourceClass {
|
||||||
|
|
||||||
private final Object source; // Class or MetaDataReader
|
private final Object source; // Class or MetadataReader
|
||||||
|
|
||||||
private final AnnotationMetadata metadata;
|
private final AnnotationMetadata metadata;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ public class Spr12334Tests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotScanTwice() {
|
public void shouldNotScanTwice() {
|
||||||
|
TestImport.scanned = false;
|
||||||
|
|
||||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
context.scan(TestImport.class.getPackage().getName());
|
context.scan(TestImport.class.getPackage().getName());
|
||||||
context.refresh();
|
context.refresh();
|
||||||
|
@ -53,14 +55,14 @@ public class Spr12334Tests {
|
||||||
|
|
||||||
public static class TestImport implements ImportBeanDefinitionRegistrar {
|
public static class TestImport implements ImportBeanDefinitionRegistrar {
|
||||||
|
|
||||||
private boolean scanned = false;
|
private static boolean scanned = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
||||||
if (this.scanned) {
|
if (scanned) {
|
||||||
throw new IllegalStateException("Already scanned");
|
throw new IllegalStateException("Already scanned");
|
||||||
}
|
}
|
||||||
this.scanned = true;
|
scanned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue