summaryrefslogtreecommitdiff
path: root/spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2014-12-03 14:31:16 +0100
committerEmmanuel Bourg <ebourg@apache.org>2014-12-03 14:31:16 +0100
commitc56370beb0a2bfa263e125fce107dceccee89fd3 (patch)
tree7ee611ceb0acbbdf7f83abcd72adb854b7d77225 /spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java
parentaa5221b73661fa728dc4e62e1230e9104528c4eb (diff)
Imported Upstream version 3.2.12
Diffstat (limited to 'spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java')
-rw-r--r--spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java
new file mode 100644
index 00000000..f6d90975
--- /dev/null
+++ b/spring-context/src/test/java/org/springframework/context/annotation/ComponentScanAnnotationIntegrationTests.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2002-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.context.annotation;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.junit.Assert.assertThat;
+import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import org.junit.Test;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
+import org.springframework.beans.factory.config.BeanDefinition;
+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.support.GenericApplicationContext;
+import org.springframework.tests.context.SimpleMapScope;
+import org.springframework.util.SerializationTestUtils;
+
+import example.scannable.CustomComponent;
+import example.scannable.CustomStereotype;
+import example.scannable.DefaultNamedComponent;
+import example.scannable.FooService;
+import example.scannable.MessageBean;
+import example.scannable.ScopedProxyTestBean;
+import example.scannable_implicitbasepackage.ComponentScanAnnotatedConfigWithImplicitBasePackage;
+import example.scannable_scoped.CustomScopeAnnotationBean;
+import example.scannable_scoped.MyScope;
+
+/**
+ * Integration tests for processing ComponentScan-annotated Configuration
+ * classes.
+ *
+ * @author Chris Beams
+ * @since 3.1
+ */
+public class ComponentScanAnnotationIntegrationTests {
+ @Test
+ public void controlScan() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.scan(example.scannable._package.class.getPackage().getName());
+ ctx.refresh();
+ assertThat("control scan for example.scannable package failed to register FooServiceImpl bean",
+ ctx.containsBean("fooServiceImpl"), is(true));
+ }
+
+ @Test
+ public void viaContextRegistration() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanAnnotatedConfig.class);
+ ctx.refresh();
+ ctx.getBean(ComponentScanAnnotatedConfig.class);
+ ctx.getBean(TestBean.class);
+ assertThat("config class bean not found", ctx.containsBeanDefinition("componentScanAnnotatedConfig"), is(true));
+ assertThat("@ComponentScan annotated @Configuration class registered directly against " +
+ "AnnotationConfigApplicationContext did not trigger component scanning as expected",
+ ctx.containsBean("fooServiceImpl"), is(true));
+ }
+
+ @Test
+ public void viaContextRegistration_WithValueAttribute() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanAnnotatedConfig_WithValueAttribute.class);
+ ctx.refresh();
+ ctx.getBean(ComponentScanAnnotatedConfig_WithValueAttribute.class);
+ ctx.getBean(TestBean.class);
+ assertThat("config class bean not found", ctx.containsBeanDefinition("componentScanAnnotatedConfig_WithValueAttribute"), is(true));
+ assertThat("@ComponentScan annotated @Configuration class registered directly against " +
+ "AnnotationConfigApplicationContext did not trigger component scanning as expected",
+ ctx.containsBean("fooServiceImpl"), is(true));
+ }
+
+ @Test
+ public void viaContextRegistration_FromPackageOfConfigClass() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanAnnotatedConfigWithImplicitBasePackage.class);
+ ctx.refresh();
+ ctx.getBean(ComponentScanAnnotatedConfigWithImplicitBasePackage.class);
+ assertThat("config class bean not found", ctx.containsBeanDefinition("componentScanAnnotatedConfigWithImplicitBasePackage"), is(true));
+ assertThat("@ComponentScan annotated @Configuration class registered directly against " +
+ "AnnotationConfigApplicationContext did not trigger component scanning as expected",
+ ctx.containsBean("scannedComponent"), is(true));
+ }
+
+ @Test
+ public void viaBeanRegistration() {
+ DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
+ bf.registerBeanDefinition("componentScanAnnotatedConfig",
+ genericBeanDefinition(ComponentScanAnnotatedConfig.class).getBeanDefinition());
+ bf.registerBeanDefinition("configurationClassPostProcessor",
+ genericBeanDefinition(ConfigurationClassPostProcessor.class).getBeanDefinition());
+ GenericApplicationContext ctx = new GenericApplicationContext(bf);
+ ctx.refresh();
+ ctx.getBean(ComponentScanAnnotatedConfig.class);
+ ctx.getBean(TestBean.class);
+ assertThat("config class bean not found", ctx.containsBeanDefinition("componentScanAnnotatedConfig"), is(true));
+ assertThat("@ComponentScan annotated @Configuration class registered " +
+ "as bean definition did not trigger component scanning as expected",
+ ctx.containsBean("fooServiceImpl"), is(true));
+ }
+
+ @Test
+ public void withCustomBeanNameGenerator() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanWithBeanNameGenenerator.class);
+ ctx.refresh();
+ assertThat(ctx.containsBean("custom_fooServiceImpl"), is(true));
+ assertThat(ctx.containsBean("fooServiceImpl"), is(false));
+ }
+
+ @Test
+ public void withScopeResolver() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ComponentScanWithScopeResolver.class);
+ // custom scope annotation makes the bean prototype scoped. subsequent calls
+ // to getBean should return distinct instances.
+ assertThat(ctx.getBean(CustomScopeAnnotationBean.class), not(sameInstance(ctx.getBean(CustomScopeAnnotationBean.class))));
+ }
+
+ @Test
+ public void withCustomTypeFilter() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ComponentScanWithCustomTypeFilter.class);
+ CustomAnnotationAutowiredBean testBean = ctx.getBean(CustomAnnotationAutowiredBean.class);
+ assertThat(testBean.getDependency(), notNullValue());
+ }
+
+ @Test
+ public void withScopedProxy() throws IOException, ClassNotFoundException {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanWithScopedProxy.class);
+ ctx.getBeanFactory().registerScope("myScope", new SimpleMapScope());
+ ctx.refresh();
+ // should cast to the interface
+ FooService bean = (FooService) ctx.getBean("scopedProxyTestBean");
+ // should be dynamic proxy
+ assertThat(AopUtils.isJdkDynamicProxy(bean), is(true));
+ // test serializability
+ assertThat(bean.foo(1), equalTo("bar"));
+ FooService deserialized = (FooService) SerializationTestUtils.serializeAndDeserialize(bean);
+ assertThat(deserialized, notNullValue());
+ assertThat(deserialized.foo(1), equalTo("bar"));
+ }
+
+ @Test
+ public void withMultipleAnnotationIncludeFilters1() throws IOException, ClassNotFoundException {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanWithMultipleAnnotationIncludeFilters1.class);
+ ctx.refresh();
+ ctx.getBean(DefaultNamedComponent.class); // @CustomStereotype-annotated
+ ctx.getBean(MessageBean.class); // @CustomComponent-annotated
+ }
+
+ @Test
+ public void withMultipleAnnotationIncludeFilters2() throws IOException, ClassNotFoundException {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanWithMultipleAnnotationIncludeFilters2.class);
+ ctx.refresh();
+ ctx.getBean(DefaultNamedComponent.class); // @CustomStereotype-annotated
+ ctx.getBean(MessageBean.class); // @CustomComponent-annotated
+ }
+
+ @Test
+ public void withBasePackagesAndValueAlias() {
+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+ ctx.register(ComponentScanWithBasePackagesAndValueAlias.class);
+ ctx.refresh();
+ assertThat(ctx.containsBean("fooServiceImpl"), is(true));
+ }
+
+}
+
+
+@Configuration
+@ComponentScan(basePackageClasses=example.scannable._package.class)
+class ComponentScanAnnotatedConfig {
+ @Bean
+ public TestBean testBean() {
+ return new TestBean();
+ }
+}
+
+@Configuration
+@ComponentScan("example.scannable")
+class ComponentScanAnnotatedConfig_WithValueAttribute {
+ @Bean
+ public TestBean testBean() {
+ return new TestBean();
+ }
+}
+
+@Configuration
+@ComponentScan
+class ComponentScanWithNoPackagesConfig { }
+
+@Configuration
+@ComponentScan(basePackages="example.scannable", nameGenerator=MyBeanNameGenerator.class)
+class ComponentScanWithBeanNameGenenerator { }
+
+class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
+ @Override
+ public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
+ return "custom_" + super.generateBeanName(definition, registry);
+ }
+}
+
+@Configuration
+@ComponentScan(basePackages="example.scannable_scoped", scopeResolver=MyScopeMetadataResolver.class)
+class ComponentScanWithScopeResolver { }
+
+class MyScopeMetadataResolver extends AnnotationScopeMetadataResolver {
+ MyScopeMetadataResolver() {
+ this.scopeAnnotationType = MyScope.class;
+ }
+}
+
+@Configuration
+@ComponentScan(basePackages="org.springframework.context.annotation",
+ useDefaultFilters=false,
+ includeFilters=@Filter(type=FilterType.CUSTOM, value=ComponentScanParserTests.CustomTypeFilter.class),
+ // exclude this class from scanning since it's in the scanned package
+ excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, value=ComponentScanWithCustomTypeFilter.class))
+class ComponentScanWithCustomTypeFilter {
+ @Bean
+ @SuppressWarnings({ "rawtypes", "serial", "unchecked" })
+ public static CustomAutowireConfigurer customAutowireConfigurer() {
+ CustomAutowireConfigurer cac = new CustomAutowireConfigurer();
+ cac.setCustomQualifierTypes(new HashSet() {{ add(ComponentScanParserTests.CustomAnnotation.class); }});
+ return cac;
+ }
+
+ public ComponentScanParserTests.CustomAnnotationAutowiredBean testBean() {
+ return new ComponentScanParserTests.CustomAnnotationAutowiredBean();
+ }
+}
+
+@Configuration
+@ComponentScan(basePackages="example.scannable",
+ scopedProxy=ScopedProxyMode.INTERFACES,
+ useDefaultFilters=false,
+ includeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, value=ScopedProxyTestBean.class))
+class ComponentScanWithScopedProxy { }
+
+@Configuration
+@ComponentScan(basePackages="example.scannable",
+ useDefaultFilters=false,
+ includeFilters={
+ @Filter(CustomStereotype.class),
+ @Filter(CustomComponent.class)
+ }
+ )
+class ComponentScanWithMultipleAnnotationIncludeFilters1 { }
+
+@Configuration
+@ComponentScan(basePackages="example.scannable",
+ useDefaultFilters=false,
+ includeFilters=@Filter({CustomStereotype.class, CustomComponent.class})
+ )
+class ComponentScanWithMultipleAnnotationIncludeFilters2 { }
+
+@Configuration
+@ComponentScan(
+ value="example.scannable",
+ basePackages="example.scannable",
+ basePackageClasses=example.scannable._package.class)
+class ComponentScanWithBasePackagesAndValueAlias { }