持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
1. 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
// 表示 @Component 注解是一个重复可用的注解
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
// 类型:默认情况下,值为 ANNOTATION 注解
FilterType type() default FilterType.ANNOTATION;
}
@Component 注解中其中存在两个方法:
includeFilters表示 spring 按照一定的规则扫描某些需要包含的组件excludeFilters表示 spring 按照一定的规则扫描某些不需要包含的组件
上面两个方法类型都是 Filter[] 数组,而Filter是一个内部注解类
1.1 测试
使用 excludeFilters :
@ComponentScan(value = {"com.shanggushenlong"},
excludeFilters = {@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class})})
@Configuration
public class MainBeanConfig {
@Bean(value = {"person01"})
public Person person() {
return new Person("张三", 28);
}
}
excludeFilters 排除type 类型为 Annotation 的 类型,Controller Service
如果排除了成功,那么只剩下 Respoitory dao
现在只剩下 dao, Controller 与 Sevice 已经被排除掉了,所以无法被扫描到
使用 includeFilters:扫描时只扫描包含某些注解的类
注:当使用 includeFilters 的时候,必需要禁用掉默认的过滤规则
在 xml 配置文件中,禁用掉默认的过滤规则
<context:component-scan base-package="com.shanggushenlong" use-default-filters="false"></context:component-scan>
使用默认属性 use-default-filters=false
使用 @ComponentScan 注解的时候,使用 useDefaultFilters = false
//@ComponentScan(value = {"com.shanggushenlong"}, excludeFilters = {
// @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})})
@ComponentScan(value = {"com.shanggushenlong"},
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})},
useDefaultFilters = false)
@Configuration
public class MainBeanConfig {
@Bean(value = {"person01"})
public Person person() {
return new Person("张三", 28);
}
}
现在只扫描 Controller.class ,容器中只存在 Controller
2、可重复使用注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
... ...
}
@Repeatable(ComponentScans.class) 表示这是一个可重复使用的注解,可以在一个类中使用多次
ComponentScans 类如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ComponentScans {
// 数组,表示可以有多个 ComponentScan
ComponentScan[] value();
}
那现在在配置类中重复使用 @ComponentScan 试试
// 让 spring 扫描含有 @Controller 注解的类
@ComponentScan(value = {"com.shanggushenlong"},
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})},
useDefaultFilters = false)
// 让 spring 扫描含有 @Service 注解的类
@ComponentScan(value = {"com.shanggushenlong"},
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Service.class})},
useDefaultFilters = false)
@Configuration
public class MainBeanConfig {
@Bean(value = {"person01"})
public Person person() {
return new Person("张三", 28);
}
}
现在容器中不仅仅有 Controller,还有 Service
注意:type=FilterType.ANNOTATION type 表示定义扫描的规则类型, ANNOTATION 表示是按照注解类型扫描
FilterType 类如下:
public enum FilterType {
// 表示类型是按照注解规则过滤
ANNOTATION,
ASSIGNABLE_TYPE,
//
ASPECTJ,
// 按照正则表达式扫描过滤
REGEX,
// 用户自定义规则过滤
CUSTOM
}
3.4 @ComponentScans 注解
重复注解使用要求是 JDK8 已以上才能用,若在此之前想要使用多个则可以使用 @ComponentScans,这是一个数组,表示里面可以设置多个 @ComponentScan 注解,具体格式如下:
@ComponentScans(value = {
@ComponentScan(value = {"com.shanggushenlong"}, includeFilters = {@ComponentScan.Filter()}),
@ComponentScan(value = {"com.shanggushenlong"}, includeFilters = {@ComponentScan.Filter()})
})
@Configuration
public class MainBeanConfig {
... ...
}
3 总结
- xml 文件配置扫描
<context:component-scan base-package="com.shanggushenlong"> - 如果不是 xml 配置文件,使用注解
@ComponentScan用于类注解,@ComponentScan(value = {"com.shanggushenlong"}),其中 value 值是扫描路径,数组,可以配置多个路径值 @ComponentScan方法:includeFilters excludeFilters两个方法都是Filter数组类型 ,includeFilters表示扫描包含哪些,excludeFilters表示扫描不包含排除哪些;Filter也是一个注解,@Filter(type = FilterType.ANNOTATION, classes = {Controller.class}), 其中 type 表示扫描过滤的类型,有注解 正则表达式 用户自定义 等多种类型@ComponentScan注解是在一个类上可多次重复使用的注解@ComponentScans可设置多个@ComponentScan