SpringBoot注解之@ComponentScan⽤法和实现原理
注解@ComponentScan的作⽤
  @Component注解及其衍⽣注解@RestController、@Controller、@Service和@Repository都是组件注册注解。@ComponentScan注解主要是从约定的扫描路径中,识别标注了组件注册注解的类,并且把这些类⾃动注册到spring IoC容器中,这些类就是我们通常所⾔的bean。IoC容器是Spring的特⾊之⼀,可以使⽤它管理bean。当然,@Configration注解修饰的类也会被托管给IoC容器。
  举个例⼦,你在微博上@某某,对⽅会优先看到这条信息,并给你反馈。同理,在Spring中,你标识⼀个@符号,那么Spring就会关照⼀下,从你这⾥拿到⼀个Bean(⾃动注册)或者给出⼀个Bean(⾃动装配)。
  思考:Spring怎么知道哪些Java类应该当作bean 注册到IoC容器中?
  解析:使⽤配置⽂件或者注解的⽅式进⾏标识需要处理的java类,这些被标注的类被Spring识别为bean类。
组件扫描路径
  注解@ComponentScan 如果不设置value属性,默认扫描路径是启动类 XxxApplication.java 所在⽬录及其⼦⽬录,所以最好还是配置value属性,减少加载时间,提⾼系统启动速度。
  ⽐如启动类在包 wiener 下⾯,那么项⽬启动时,会默认扫描wiener包及其⼦包下的所有类。也就是说,即便不明确标注
@ComponentScan,Spring Boot也会⾃动搜索当前应⽤主⼊⼝⽬录及其下⽅⼦⽬录。如果其它包中的bean 不在当前主包路径下⾯,则应使⽤@ComponentScan设置value属性,配置扫描路径。如果定义了错误的扫描路径,那么在使⽤注解@Autowired⾃动装配Bean时会出错,报a bean of type that could not be found错误。
配置扫描路径
  @ComponentScan注解既可以扫描包,也可以扫描指定的类。我们只需要指定⼀个需要扫描的路径,就可以达到更改扫描路径的⽬的。
springboot和过滤器1. 包路径
  通过value属性设置需要扫描的包:
@ComponentScan({"company.user","company.service"})
2. 类路径
  通过basePackageClasses属性指定需要扫描的类:
@ComponentScan(basePackageClasses={XxxService.class, YyyService.class})
@Component和@ComponentScan的区别
  @Component和@ComponentScan有什么区别?⼆者⽤于不同⽬的,咱们结合学⽣抢答⽼师的问题这⼀场景来解释。@Component表⽰哪些类可能是bean的候选者,就像哪些同学举⼿抢答问题⼀样。@ComponentScan 搜索组件包中的类,到所有bean的候选者,就像⽼师试图出哪些同学举⼿抢答问题。通俗⼀点解释,就是全班同学代表扫描路径下的所有类,抢答者就是被@Component注解修饰的类,⽽到所有抢答者的⽼师就是@ComponentScan。延伸⼀点,成功抢到答题机会的同学就是被@Autowire装配的bean了。
注解@ComponentScan实现原理
  本节介绍 Spring Boot 中注解 @ComponentScan 的实现原理。
  下⾯介绍⼀下ComponentScan注解中⼏个常⽤的属性。
1. String[] value() default {};
指定包扫描路径,value属性的值,就是项⽬中的⼀个具体路径。value属性的类型是String数组,也就是⽀持⼀次指定多个包扫描路径。这个属性上⾯添加了⼀个注解,@AliasFor("basePackages"),这个注解的意思就是说,value这个属性等价于basePackages属性。关于basePackages属性,下⾯会讲到。
2. Class<?>[] basePackagesClasses() default {};
扫描具体的类。basePackagesClasses属性的类型是Class数组,也就是说⽀持同时指定多个扫描类。
3. Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator. class;
配置beanName⽣成器,默认是BeanNameGenerator。⼀般情况下,我们都是使⽤默认的beanName⽣成器,但是Spring实现了beanName⽣成器的可配置。
4. boolean useDefaultFilters() default true;
是否对含有以下注解的类开启检测,默认是开启的。
@Component
@Repository
@Service
@Controller
5. ComponentScan.Filter[] includeFilters() default {};
指定某些Filter扫描到的类。听起来有些费劲,说⽩了就是指定了类型,扫描指定的这些类型。可选类型有5种,定义在枚举类FilterType中:
第⼀种:ANNOTATION
第⼆种:ASSIGNABLE_TYPE
第三种:ASPECTJ
第四种:REGEX,正则表达式。
第五种:CUSTOM,⾃定义类型。
6. ComponentScan.Filter[] excludeFilters() default {};
排除过滤器扫描的的类。
Reference