Prevent duplicate @Import processing

Refactor ConfigurationClassParser to recursively find values from
all @Import annotations, combining them into a single unique set.

This change prevents ImportBeanDefinitionRegistrars from being
invoked twice.

Issue: SPR-9925
This commit is contained in:
Phillip Webb
2012-10-30 22:13:15 -07:00
committed by Chris Beams
parent e6c4840356
commit 6d8b37d8bb
2 changed files with 84 additions and 43 deletions

View File

@@ -25,10 +25,14 @@ import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor;
import org.springframework.util.Assert;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
@@ -77,6 +81,24 @@ public class ImportAwareTests {
assertThat(foo, is("xyz"));
}
@Test
public void importRegistrar() throws Exception {
ImportedRegistrar.called = false;
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ImportingRegistrarConfig.class);
ctx.refresh();
assertNotNull(ctx.getBean("registrarImportedBean"));
}
@Test
public void importRegistrarWithImport() throws Exception {
ImportedRegistrar.called = false;
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ImportingRegistrarConfigWithImport.class);
ctx.refresh();
assertNotNull(ctx.getBean("registrarImportedBean"));
assertNotNull(ctx.getBean(ImportedConfig.class));
}
@Configuration
@Import(ImportedConfig.class)
@@ -131,4 +153,35 @@ public class ImportAwareTests {
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
}
}
@Configuration
@EnableImportRegistrar
static class ImportingRegistrarConfig {
}
@Configuration
@EnableImportRegistrar
@Import(ImportedConfig.class)
static class ImportingRegistrarConfigWithImport {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ImportedRegistrar.class)
public @interface EnableImportRegistrar {
}
static class ImportedRegistrar implements ImportBeanDefinitionRegistrar {
static boolean called;
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(String.class.getName());
registry.registerBeanDefinition("registrarImportedBean", beanDefinition );
Assert.state(called == false, "ImportedRegistrar called twice");
called = true;
}
}
}