【Spring注解】@ComponentScan之includeFilters和excludeFilters

源码:https://github.com/nieandsun/spring-study

1. 概念

1.1 先看一段代码

在这里插入图片描述

1.2 type—FilterType

FilterType为一个枚举类,总共有5个值,也就是说type总共有5个可选值

public enum FilterType {
	ANNOTATION,//按照注解方式
	ASSIGNABLE_TYPE,//按照指定类型的方式
	ASPECTJ,//使用ASPECTJ表达式的方式-------没用过,不演示
	REGEX,//利用正则表达式进行指定-----------没用过,不演示
	CUSTOM//自己实现TypeFilter接口进行自定义规则(如下面的代码)
}

1.3 实现TypeFilter接口—自定义规则

下面的代码

  • 如果放在excludeFilters里,会过滤掉含有Buy字符的类-----即不扫描
  • 如果放在includeFilters里,会扫描含有Buy字符的类---------扫描
package com.nrsc.springstudy.c1_componentscan1.study2.config;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

public class NrscTypeFilter implements TypeFilter {

    private ClassMetadata classMetadata;

    /**
     * MetadataReader:读取到当前正在扫描类的信息
     * MetadataReaderFactory:可以获取到其他任何类信息
     */
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //获取当前类注解的信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //获取当前正在扫描的类信息
        classMetadata = metadataReader.getClassMetadata();
        //获取当前类资源(类的路径)
        Resource resource = metadataReader.getResource();

        String className = classMetadata.getClassName();
        System.out.println("----->" + className);
        //当类包含Buy字符, 则匹配成功,返回true
        //excludeFilters返回true---->会被过滤掉
        //includeFilters返回true---->会通过
        if (className.contains("Buy")) {
            return true;
        }
        return false;
    }
}

2 .代码演示—以excludeFilters为例

Config1配置类的代码如下图所示,代码中的NrscTypeFilter 即为上面的代码.
在这里插入图片描述
按照代码以及项目的目录结构可以猜出,config1_test中的类只有OrderController1能被注册到spring容器中.
在这里插入图片描述

3.includeFilters&useDefaultFilters = false

3.1 为何

  • 如下图,当使用includeFilters想只扫描含有@Service注解的类时,必须要加上useDefaultFilters = false

在这里插入图片描述
先验证一下效果
在这里插入图片描述
再简单说下原因:
其实@Component,@Controller,@Service和@Repository三者功能相同,后三个注解是为了对应后端代码的三层结构由第一个注解"复制"而来的.查看源码可以发现,后三个注解上面都有一个@Component.

  • 也就是说@Controller,@Service和@Repository除了是它们自己,也是一个@Component
  • 在进行includeFilters过滤时,如果useDefaultFilters =true,它会默认把所有包含@Component注解的类都进行扫描

因此只有加上useDefaultFilters=false才能得到正确的结果

3.2 多说几句

真的懂了上面我说的原因,你肯定就不会为使用下面的配置类,能扫描到所有含有@Component,@Controller,@Service和@Repository注解的类而疑惑了.

@Configuration
@ComponentScan(value = "com.nrsc.springstudy.c1_componentscan1.study2.config2_test",
        includeFilters = {
                @Filter(type = FilterType.ANNOTATION, classes = {Component.class})},
        useDefaultFilters = false)
public class Config3 {
  • 14
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值