spring的自动扫描机制,注解使用ComponentScan
@ComponentScan(basePackages = {"context.cache"})
其内部使用ClassPathBeanDefinitionScanner来实现,
ClassPathBeanDefinitionScanner会扫描包名下面带@Service注解相关的类,然后转解析为BeanDefinition,最后完成自动扫描注册
ClassPathBeanDefinitionScanner构建函数需要传入一个BeanDefinitionRegistry实例对象
测试代码:
public class ClassPathBeanDefinitionScannerTests {
private static final String BASE_PACKAGE = "example.scannable";
@Test
public void testSimpleScanWithDefaultFiltersAndPostProcessors() {
GenericApplicationContext context = new GenericApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
int beanCount = scanner.scan(BASE_PACKAGE);
assertEquals(13, beanCount);
assertTrue(context.containsBean("serviceInvocationCounter"));
assertTrue(context.containsBean("fooServiceImpl"));
assertTrue(context.containsBean("stubFooDao"));
assertTrue(context.containsBean("myNamedComponent"));
assertTrue(context.containsBean("myNamedDao"));
assertTrue(context.containsBean("thoreau"));
assertTrue(context.containsBean(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
assertTrue(context.containsBean(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
assertTrue(context.containsBean(AnnotationConfigUtils.REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
assertTrue(context.containsBean(AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
assertTrue(context.containsBean(AnnotationConfigUtils.EVENT_LISTENER_PROCESSOR_BEAN_NAME));
assertTrue(context.containsBean(AnnotationConfigUtils.EVENT_LISTENER_FACTORY_BEAN_NAME));
context.refresh();
FooServiceImpl fooService = context.getBean("fooServiceImpl", FooServiceImpl.class);
assertTrue(context.getDefaultListableBeanFactory().containsSingleton("myNamedComponent"));
assertEquals("bar", fooService.foo(123));
assertEquals("bar", fooService.lookupFoo(123));
assertTrue(context.isPrototype("thoreau"));
}
}