Spring如何玩转扫描包?
当我们指定包名basePackages, 如@ComponentScan(basePackages = “cn.zhutan.myspringtest”), Spring会去加载该文件夹下面的class文件, 封装成MetadataReader元信息, 根据元信息判断哪些类需要创建bean, 哪些类不需要创建bean, 而这个判断条件, Spring提供了很强大的扩展, 有以下几种情况
- 根据贴上某注解判断创建或者不创建bean
- 指定某些类创建或者不创建bean
- 根据正则匹配哪些bean创建或者不创建
- 根据Aspectj判断bean的创建与否
- 根据用户写的规则判断bean的创建与否
Spring如何指定过滤规则?
在注解@ComponentScan中有几个核心属性
- includeFilters, 表示满足该过滤条件时, 要创建bean
- excludeFilters, 表示满足该过滤条件时, 不创建bean
- useDefaultFilters, 表示是否使用默认的过滤器, 默认是true, Spring内部则相当于在includeFilters加入了过滤规则, 即满足加了@Component的类会创建bean, 如果我们置为false, 即使我们加了@Component也不会创建bean
查看注解@ComponentScan源码
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
// 省略其他...
// 是否使用默认过滤器
boolean useDefaultFilters() default true;
// 满足条件要注入的bean
ComponentScan.Filter[] includeFilters() default {
};
// 满足条件不注入的bean
ComponentScan.Filter[] excludeFilters() default {
};
// 省略其他...
@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 {
};
}
}
includeFilters和excludeFilters需要参数为数组ComponentScan.Filter[], 表示可以配置多个过滤条件,
每个过滤条件都是ComponentScan.Filter对象, 而是过滤条件的种类是以type属性指定的
public enum FilterType {
// 1. 根据贴上某注解判断创建或者不创建bean, 解析类AnnotationTypeFilter
ANNOTATION,