spring5学习系列之------2 给容器注册组件二 @ComponentScan 自定义扫描规则,过滤组件

         最近几篇博客是作者对自己是之前工作中对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注入,那么就会报错 )

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值