Investigate issue with @ComponentScan as meta-annotation

This commit introduces unit and integration tests that attempt to
reproduce the issue claimed by the reporter in SPR-11557. However, the
tests pass without any problems.

Issue: SPR-11557
This commit is contained in:
Sam Brannen 2014-03-15 00:04:53 +01:00
parent 3d506eb033
commit f1fbe85ff1
2 changed files with 71 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,10 @@
package org.springframework.context.annotation;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.HashSet;
import example.scannable.CustomComponent;
@ -28,8 +32,8 @@ import example.scannable.ScopedProxyTestBean;
import example.scannable_implicitbasepackage.ComponentScanAnnotatedConfigWithImplicitBasePackage;
import example.scannable_scoped.CustomScopeAnnotationBean;
import example.scannable_scoped.MyScope;
import org.junit.Test;
import org.junit.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
import org.springframework.beans.factory.config.BeanDefinition;
@ -37,6 +41,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScanParserTests.CustomAnnotationAutowiredBean;
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.tests.context.SimpleMapScope;
import org.springframework.util.SerializationTestUtils;
@ -50,8 +55,10 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.1
*/
@SuppressWarnings("resource")
public class ComponentScanAnnotationIntegrationTests {
@Test
@ -101,6 +108,20 @@ public class ComponentScanAnnotationIntegrationTests {
ctx.containsBean("scannedComponent"), is(true));
}
@Test
public void viaContextRegistration_WithComposedAnnotation() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ComposedAnnotationConfig.class);
ctx.refresh();
ctx.getBean(ComposedAnnotationConfig.class);
ctx.getBean(SimpleComponent.class);
assertThat("config class bean not found",
ctx.containsBeanDefinition("componentScanAnnotationIntegrationTests.ComposedAnnotationConfig"), is(true));
assertThat("@ComponentScan annotated @Configuration class registered directly against "
+ "AnnotationConfigApplicationContext did not trigger component scanning as expected",
ctx.containsBean("simpleComponent"), is(true));
}
@Test
public void viaBeanRegistration() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@ -209,6 +230,22 @@ public class ComponentScanAnnotationIntegrationTests {
assertThat(ctx.containsBean("fooServiceImpl"), is(true));
}
@Configuration
@ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface ComposedConfiguration {
String[] basePackages() default {};
String[] bundles() default {};
}
@ComposedConfiguration(basePackages = "org.springframework.context.annotation.componentscan.simple")
public static class ComposedAnnotationConfig {
}
}

View File

@ -16,6 +16,11 @@
package org.springframework.context.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.scope.ScopedObject;
@ -29,6 +34,8 @@ import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.componentscan.simple.SimpleComponent;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DescriptiveResource;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
@ -103,6 +110,16 @@ public class ConfigurationClassPostProcessorTests {
assertSame(foo, bar.foo);
}
@Test
public void postProcessorWorksWithComposedAnnotations() {
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(ComposedAnnotationConfig.class));
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
pp.setEnvironment(new StandardEnvironment());
pp.postProcessBeanFactory(beanFactory);
SimpleComponent simpleComponent = beanFactory.getBean(SimpleComponent.class);
assertNotNull(simpleComponent);
}
@Test
public void postProcessorOverridesNonApplicationBeanDefinitions() {
RootBeanDefinition rbd = new RootBeanDefinition(TestBean.class);
@ -610,4 +627,19 @@ public class ConfigurationClassPostProcessorTests {
}
}
@Configuration
@ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface ComposedConfiguration {
String[] basePackages() default {};
String[] bundles() default {};
}
@ComposedConfiguration(basePackages = "org.springframework.context.annotation.componentscan.simple")
public static class ComposedAnnotationConfig {
}
}