@ComponentScan

作用

  自动扫描包名下所有使用@Service,@Component,@Repository和@Controller的类,并注册为Bean;

工作原理

  要创建Bean的class文件集合形成扫描路径,传入@ComponentScan,然后由ComponentScanAnnotationParser或者ClassPathBeanDefinitionScanner对扫描路径下的class文件扫描解析,如下图所示:
这里写图片描述

ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner扫描器内部的处理过程整理如下:

  1. 遍历basePackages,根据每个basePackage找出这个包下的所有的class。比如basePackage为your/pkg,会找出your.pkg包下所有的class。找出之后封装成Resource接口集合,这个Resource接口是Spring对资源的封装,有FileSystemResource、ClassPathResource、UrlResource实现等;
  2. 遍历找到的Resource集合,通过includeFilters和excludeFilters判断是否解析。这里的includeFilters和excludeFilters是TypeFilter接口类型的集合,是ClassPathBeanDefinitionScanner内部的属性。TypeFilter接口是一个用于判断类型是否满足要求的类型过滤器。excludeFilters中只要有一个TypeFilter满足条件,这个Resource就会被过滤。includeFilters中只要有一个TypeFilter满足条件,这个Resource就不会被过滤;
  3. 如果没有被过滤把Resource封装成ScannedGenericBeanDefinition添加到BeanDefinition结果集中;
  4. 返回最后的BeanDefinition结果集;

默认过滤器

/**
     * Create a ClassPathScanningCandidateComponentProvider with a {@link StandardEnvironment}.
     * @param useDefaultFilters whether to register the default filters for the
     * {@link Component @Component}, {@link Repository @Repository},
     * {@link Service @Service}, and {@link Controller @Controller}
     * stereotype annotations
     * @see #registerDefaultFilters()
     */
    public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) {
        this(useDefaultFilters, new StandardEnvironment());
    }

Spring Boot调用链路

这里写图片描述

参考:

  1. https://fangjian0423.github.io/2017/06/11/spring-custom-component-provider/
  2. https://blog.csdn.net/u014042066/article/details/80366042

猜你喜欢

转载自blog.csdn.net/yangguosb/article/details/80860376