@ComponentScan 的作用就是根据定义的扫描路径,把符合扫描规则的类装配到spring容器中,注解定义如下。
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Repeatable(ComponentScans.class) public @interface ComponentScan { @AliasFor("basePackages") String[] value() default {}; @AliasFor("value") String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class; ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT; String resourcePattern() default "**/*.class"; boolean useDefaultFilters() default true; ComponentScan.Filter[] includeFilters() default {}; ComponentScan.Filter[] excludeFilters() default {}; boolean lazyInit() default false; @Retention(RetentionPolicy.RUNTIME) @Target({}) public @interface Filter { FilterType type() default FilterType.ANNOTATION; @AliasFor("classes") Class<?>[] value() default {}; @AliasFor("value") Class<?>[] classes() default {}; String[] pattern() default {}; } }
basePackages与value:
用于指定包的路径,进行扫描。默认情况下是扫描配置类所在的包及其子包下的类
basePackageClasses:
用于指定某个类的包的路径进行扫描
nameGenerator:
bean的名称的生成器
useDefaultFilters:
是否开启对@Component,@Repository,@Service,@Controller的类进行检测
(1)默认情况下是true。在basePackages指定的路径以及子路径下所有被@Component ,@Repository,@Service,@Controller注解标记的类都会被扫描,并注入到Spring 容器。
(2)如果useDefaultFilters的是false话,不扫描 在basePackages指定的路径以及子路径下所有被@Component ,@Repository,@Service,@Controller注解标记的类,这些类即使被上面四个注解标记,也不会注入到Spring容器中。
includeFilters:
包含的过滤条件,一般当useDefaultFilters的值为false时使用,当useDefaultFilters为false时,includeFilters指定的就是需要进行扫描并注入的条件
FilterType.ANNOTATION:按照注解过滤
FilterType.ASSIGNABLE_TYPE:按照给定的类型
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:正则
FilterType.CUSTOM:自定义规则
excludeFilters:
排除的过滤条件,一般useDefaultFilters为true时使用,excludeFilters的指就是basePackages指定的路径以及子路径下排除的条件。
案例1
@Configuration @ComponentScan(basePackages = {"com.zhang"}, useDefaultFilters=true, excludeFilters ={@Filter(type=FilterType.ANNOTATION,classes={Controller.class}), @Filter(type=FilterType.ANNOTATION,classes={Service.class})})
(1)basePaceages指定了 com.zhang这个包,useDefaultFilters的值为true。如果不考虑excludeFilters ,这个两个属性组合的起来就是在 com.zhang及其子包下所有被@Component ,@Repository,@Service,@Controller这四个注解标注的类,都会被扫描并注入到Spring容器中。
(2)excludeFilters 属性指定了要排除掉被@Controller与@Service两个注解。在basePaceages与useDefaultFilters两个属性的基础上进行排除,那么最后扫描的就是 com.zhang包及其子包下的被@Component ,@Repository标记的类。
案例2
@ComponentScan(basePackages = {"com.zhang"}, useDefaultFilters=false, includeFilters ={@Filter(type=FilterType.ANNOTATION,classes={Controller.class})})
includeFilters 也是在basePackages与useDefaultFilters组合后的基础上添加一些特定的类。本例中的意思是只扫描com.zhang及其子包下被@Controller注解标记的类