ComponentScan annotation allows for registering beans with lazy initialization
Issue: SPR-10459
This commit is contained in:
parent
ef51d4dbdb
commit
f2e4ad2364
|
@ -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.
|
||||
|
@ -163,6 +163,14 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
|
|||
(beanDefinitionDefaults != null ? beanDefinitionDefaults : new BeanDefinitionDefaults());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the defaults to use for detected beans (never {@code null}).
|
||||
* @since 4.1
|
||||
*/
|
||||
public BeanDefinitionDefaults getBeanDefinitionDefaults() {
|
||||
return this.beanDefinitionDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name-matching patterns for determining autowire candidates.
|
||||
* @param autowireCandidatePatterns the patterns to match against
|
||||
|
|
|
@ -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.
|
||||
|
@ -132,6 +132,13 @@ public @interface ComponentScan {
|
|||
*/
|
||||
Filter[] excludeFilters() default {};
|
||||
|
||||
/**
|
||||
* Specify whether scanned beans should be registered for lazy initialization.
|
||||
* <p>Default is {@code false}; switch this to {@code true} when desired.
|
||||
* @since 4.1
|
||||
*/
|
||||
boolean lazyInit() default false;
|
||||
|
||||
|
||||
/**
|
||||
* Declares the type filter to be used as an {@linkplain ComponentScan#includeFilters()
|
||||
|
|
|
@ -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.
|
||||
|
@ -106,6 +106,11 @@ class ComponentScanAnnotationParser {
|
|||
}
|
||||
}
|
||||
|
||||
boolean lazyInit = componentScan.getBoolean("lazyInit");
|
||||
if (lazyInit) {
|
||||
scanner.getBeanDefinitionDefaults().setLazyInit(true);
|
||||
}
|
||||
|
||||
List<String> basePackages = new ArrayList<String>();
|
||||
for (String pkg : componentScan.getStringArray("value")) {
|
||||
if (StringUtils.hasText(pkg)) {
|
||||
|
|
|
@ -23,7 +23,17 @@ import java.lang.annotation.RetentionPolicy;
|
|||
import java.lang.annotation.Target;
|
||||
import java.util.HashSet;
|
||||
|
||||
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;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
@ -36,16 +46,6 @@ 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;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
|
||||
|
@ -116,10 +116,10 @@ public class ComponentScanAnnotationIntegrationTests {
|
|||
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));
|
||||
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
|
||||
|
@ -159,7 +159,8 @@ public class ComponentScanAnnotationIntegrationTests {
|
|||
@Test
|
||||
public void withCustomTypeFilter() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ComponentScanWithCustomTypeFilter.class);
|
||||
KustomAnnotationAutowiredBean testBean = ctx.getBean(KustomAnnotationAutowiredBean.class);
|
||||
assertFalse(ctx.getDefaultListableBeanFactory().containsSingleton("kustomBean"));
|
||||
KustomAnnotationAutowiredBean testBean = ctx.getBean("kustomBean", KustomAnnotationAutowiredBean.class);
|
||||
assertThat(testBean.getDependency(), notNullValue());
|
||||
}
|
||||
|
||||
|
@ -294,7 +295,8 @@ class MyScopeMetadataResolver extends AnnotationScopeMetadataResolver {
|
|||
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))
|
||||
excludeFilters=@Filter(type=FilterType.ASSIGNABLE_TYPE, value=ComponentScanWithCustomTypeFilter.class),
|
||||
lazyInit = true)
|
||||
class ComponentScanWithCustomTypeFilter {
|
||||
@Bean
|
||||
@SuppressWarnings({ "rawtypes", "serial", "unchecked" })
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2010 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,7 @@
|
|||
package org.springframework.context.annotation;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
@ -29,6 +30,7 @@ import org.springframework.core.type.filter.TypeFilter;
|
|||
* @see ComponentScanAnnotationIntegrationTests
|
||||
*/
|
||||
public class ComponentScanAnnotationTests {
|
||||
|
||||
@Test
|
||||
public void noop() {
|
||||
// no-op; the @ComponentScan-annotated MyConfig class below simply excercises
|
||||
|
@ -36,7 +38,9 @@ public class ComponentScanAnnotationTests {
|
|||
}
|
||||
}
|
||||
|
||||
@interface MyAnnotation { }
|
||||
|
||||
@interface MyAnnotation {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
|
@ -44,18 +48,19 @@ public class ComponentScanAnnotationTests {
|
|||
nameGenerator = DefaultBeanNameGenerator.class,
|
||||
scopedProxy = ScopedProxyMode.NO,
|
||||
scopeResolver = AnnotationScopeMetadataResolver.class,
|
||||
useDefaultFilters = false,
|
||||
resourcePattern = "**/*custom.class",
|
||||
useDefaultFilters = false,
|
||||
includeFilters = {
|
||||
@Filter(type = FilterType.ANNOTATION, value = MyAnnotation.class)
|
||||
},
|
||||
excludeFilters = {
|
||||
@Filter(type = FilterType.CUSTOM, value = TypeFilter.class)
|
||||
}
|
||||
},
|
||||
lazyInit = true
|
||||
)
|
||||
class MyConfig {
|
||||
|
||||
}
|
||||
|
||||
@ComponentScan(basePackageClasses=example.scannable.NamedComponent.class)
|
||||
class SimpleConfig { }
|
||||
class SimpleConfig {
|
||||
}
|
||||
|
|
|
@ -21,7 +21,10 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import example.profilescan.ProfileAnnotatedComponent;
|
||||
import example.scannable.AutowiredQualifierFooService;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
@ -29,9 +32,7 @@ import org.springframework.context.support.GenericXmlApplicationContext;
|
|||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
import example.profilescan.ProfileAnnotatedComponent;
|
||||
import example.scannable.AutowiredQualifierFooService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -134,13 +135,13 @@ public class ComponentScanParserTests {
|
|||
* Intentionally spelling "custom" with a "k" since there are numerous
|
||||
* classes in this package named *Custom*.
|
||||
*/
|
||||
@Component("kustomBean")
|
||||
public static class KustomAnnotationAutowiredBean {
|
||||
|
||||
@Autowired
|
||||
@CustomAnnotation
|
||||
private KustomAnnotationDependencyBean dependency;
|
||||
|
||||
|
||||
public KustomAnnotationDependencyBean getDependency() {
|
||||
return this.dependency;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue