前言

Spring可以通过两种方式启用Bean的自动扫描
一种是:

另一种是:

@ComponentScan(‘xxx’)

context:component-scan实现原理

配置这个标签,spring会开启注解扫描

By default, the Spring-provided @Component, @Repository, @Service, @Controller, @RestController, @ControllerAdvice, and @Configuration stereotypes will be detected. 隐式开启注解配置:,并激活@Required, @Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit这几个注解。

标签处理器: ComponentScanBeanDefinitionParser
注册Component处理逻辑如下:
component-scan处理annotation-config=true, 表示默认会注册AnnotationPostProcessors

  1. // Register annotation config processors, if necessary.
  2. boolean annotationConfig = true;
  3. if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
  4. annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
  5. }
  6. if (annotationConfig) {
  7. Set<BeanDefinitionHolder> processorDefinitions =
  8. AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
  9. for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
  10. compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
  11. }
  12. }

通过AnnotationConfigUtils.registerAnnotationConfigProcessors方法注册多个注解处理器BeanDefinition。

  1. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  2. // xml的方式仍然兼容: @Confirguration @ComponentScan @Import 等
  3. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  4. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  5. def.setSource(source);
  6. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  7. }
  8. // 处理@Autowirded @Value
  9. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  10. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  11. def.setSource(source);
  12. beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  13. }
  14. // 处理@Resource @PostConstruct 等
  15. // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  16. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  17. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  18. def.setSource(source);
  19. beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  20. }

ComponentScan实现原理

与xml方式类似,都是委托ClassPathBeanDefinitionScanner作Bean扫描。