spring 创建注解(@Service @Component 等)扫描器源码解析(三)

上一篇介绍spring 自定义扫描标签解析过程,中间有个重要的知识点我们单独取出来分析,就是注解扫描器的创建

1、ComponentScanBeanDefinitionParser implements BeanDefinitionParser 这里开始创建

@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
   //获取basePackage属性
   String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
   basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
   //可以用逗号分开
   String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
         ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

   //创建注解扫描器,今天从这里开始,点击进入
   ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
   //扫描并把扫描的类封装成beanDefinition对象  核心方法,重要程度 5
   Set beanDefinitions = scanner.doScan(basePackages);
   registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

   return null;
}
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
   //使用默认的过滤器
   boolean useDefaultFilters = true;
   //@Service @Component  默认filter
   if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
      useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
   }

   //从这里开始  创建注解的扫描器
   ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
   scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
   scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
 //删除部分代码
   try {
      parseBeanNameGenerator(element, scanner);
   }
   try {
      parseScope(element, scanner);
   }
   parseTypeFilters(element, scanner, parserContext);

   return scanner;
}
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
//点击进入
   return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
         readerContext.getEnvironment(), readerContext.getResourceLoader());
}

2、ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment, @Nullable ResourceLoader resourceLoader) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   this.registry = registry;

   //使用默认的过滤器
   if (useDefaultFilters) {
      //默认的 注解@Service @Component  点击进入
      registerDefaultFilters();
   }
   setEnvironment(environment);
   setResourceLoader(resourceLoader);
}

3、 ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware

protected void registerDefaultFilters() {
   //过滤器中添加需要扫描的注解类型,把componet 注解包装 同时也处理了@server注解,一样它继承了compont注解
   this.includeFilters.add(new AnnotationTypeFilter(Component.class));
   ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
   //删除不重要的
}

4、

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@org.springframework.stereotype.Component//继承了compont注解
public @interface Service {

   /**
    * The value may indicate a suggestion for a logical component name,
    * to be turned into a Spring bean in case of an autodetected component.
    * @return the suggested component name, if any (or empty String otherwise)
    */
   @AliasFor(annotation = org.springframework.stereotype.Component.class)
   String value() default "";

}

5、到这里大家应该豁然开朗了吧,项目中常用的注解 @Component @Service  在这里开始进入我们视线。下篇我们介绍类里面的注解问题,大家可以先思考一下。敬请期待!

 

你可能感兴趣的:(spring源码学习)