最近几篇博客是作者对自己是之前工作中对spring的一个回顾和总结,比较基础,但是也有一些细节之前用的比较少,这次查漏补缺中,在上篇博客中介绍了对spring的IOC容器注册组件的一个方法,我们不可能把所有的bean都用Bean的注解给注入到容器中,所以本文介绍注册到容器中的第二种方式,使用包扫描的方式去注册到容器中,并且还在包扫描的基础上,加点自定义的规则
首先建立一个controller service dao 分别标注上 @Controller @Service @Repository,并且 在config上指定包扫描的范围加上@ComponentScan注解,整体结构如图

编写测试类

会发现都扫描到了 包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类],那么我们点开@ComponentScan看一下源码,会发现有两个属性是Filter[] 类型的,因此我们再次点开Filter,

filte也是一个注解,里面会有根据type来过滤,所以,看懂源码之后这么指定过滤规则
@Configuration
@ComponentScan(value = "com.study.chap3",excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
Service.class, Repository.class
})
})
public class Config {
}
excludeFilters表示排除,根据什么排除呢,具体就是Filter来实现,里面type表示排除根据注解排除,classes来指定相关注解,那么现在排除弄好了,如何用上包含呢,那就需要用到 includeFilters,并且要把默认的扫包规则给禁用,因为默认扫包规则就是从源码里面只要标注了有@Component注解都扫描
@Configuration
@ComponentScans({
@ComponentScan(value = "com.study.chap3",includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
Controller.class
})
},useDefaultFilters = false)
})
public class Config {
}
一样这样写的话可以只把controller扫描到 既然这样我们能看到Filter的内部是条件,那我们去看看Filter的源码

filter大概有这几种,基本上总结一下 excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件
FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照给定的类型;比如 Bean的类型
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则 ,该规则需要自己实现,并且实现TypeFilter的接口
public class MyTypeFilter implements TypeFilter {
/**
* metadataReader:读取到的当前正在扫描的类的信息
* metadataReaderFactory:可以获取到其他任何类信息的
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// TODO Auto-generated method stub
//获取当前类注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
System.out.println("--->"+className);
return className.contains("er");
}
}
自定义过滤类写完了之后 ,在 @ComponentScan去使用
@Configuration
@ComponentScans({
@ComponentScan(value = "com.study.chap3",includeFilters = {
/* @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {
Controller.class}),*/
@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
})
public class Config {
}
输出之后会发现确实 自定义的过滤类生效。

至此,我们学到了 @ComponentScans 以及 @ComponentScan 扫包的过滤 自定义规则等等 ,以及常用注解@Controller@Service/@Repository/@Component,顺便提一句,如果在定义扫包过滤的时候,但是相关的组件又有牵扯就会报错(比如 扫包的时候我们只要controller 但是controller里面又有service注入,那么就会报错 )
来源:CSDN
作者:xzjayx
链接:https://blog.csdn.net/xzjayx/article/details/104106597