专栏首页技术进阶之路Spring 注解开发之 @ComponentScan

Spring 注解开发之 @ComponentScan

这次介绍一下 Spring 中比较重要的一个注解 @ComponentScan

本文的组织结构如下:

  • 先看一下该注解取代了配置文件中的哪些配置;
  • 再总览该注解有哪些属性值;
  • 最后讲解一下重要的属性值。

Spring 版本 5.1.2.RELEASE

一、XML 配置

@ComponentScan 注解取代了配置文件中的如下配置:

<context:component-scan base-package="top.wsuo"/>

这一行配置的意思是开启包扫描,会自动扫描带有 @component 及其 衍生注解 的类:,将其放入容器中。

该配置还有一个属性:use-default-filters,将其设为 false 即代表不使用默认的 include 规则,而使用自己规定的规则。该配置对应于@ComponentScan 的同名属性值。

二、属性总览

来看一下下面这个注解:

@ComponentScan(
        value = "top.wsuo",
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
                        Controller.class, Service.class
                })
        },
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
                        Repository.class
                })
        },
        useDefaultFilters = false
)
  • value 指定要扫描的包路径;
  • excludeFilters 指定排除的规则;
  • includeFilters 指定包含的规则,要想该属性生效需设置 useDefaultFilters = false

三、重要属性讲解

重要属性是 excludeFilters 以及 includeFilters,两属性类似,这里以前者为例:

/**
* Specifies which types are not eligible for component scanning.
* @see #resourcePattern
*/
Filter[] excludeFilters() default {};

1、Filter 子注解

该属性值需要一个 Filter 数组,而 FilterComponentScan 的一个内部类,是一个子注解。

该注解的基本使用如下:

@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
	Controller.class, Service.class
})

该注解有两个属性值比较重要:

  • type:规定使用哪一种模式过滤掉类;
  • value:给出具体的值,注解就给类型,正则就给匹配规则等等······

拆解上面的例子分析:

泛型 FilterType 规定几种候选的模式,默认是 ANNOTATION 即根据注解排除:

FilterType type() default FilterType.ANNOTATION;

属性 classesvalue ,根据前面规定的模式传值:

@AliasFor("classes")
Class<?>[] value() default {};

2、FilterType 泛型

type 取值的泛型类 FilterType 有以下几种取值:

  • ANNOTATION:使用注解过滤;
  • ASSIGNABLE_TYPE:使用给定的类型;
  • ASPECTJ:使用 ASPECTJ 表达式;
  • REGEX:使用正则表达式;
  • CUSTOM:使用自定义规则,需要提供一个 TypeFilter 的实现类;

3、自定义过滤规则

TypeFilter 是一个接口,需要我们提供一个实现类,实现一个方法:

/**
* 设置匹配规则
 *
 * @param metadataReader        读取当前正在扫描的类的信元数据
 * @param metadataReaderFactory 可以获取其他任何类的元数据
 * @return 返回匹配情况
 * @throws IOException IO异常
 */
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException

该方法有两个参数:

  • metadataReader:读取当前正在扫描的类的信元数据;
  • metadataReaderFactory:可以获取其他任何类的元数据。

其中 metadataReader 对象有下面几个常用的方法:

// 获取当前类的注解元数据
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 获取当前正在扫描的类的元数据
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 获取当前类资源(类的路径)
Resource resource = metadataReader.getResource();

我们可以通过获取正在扫描的类来决定是加入到容器中还是不加入。

private static final String RULES = "er";
/**
 * 设置匹配规则
 *
 * @param metadataReader        读取当前正在扫描的类的信元数据
 * @param metadataReaderFactory 可以获取其他任何类的元数据
 * @return 返回匹配情况
 * @throws IOException IO异常
 */
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
    // 获取当前类的注解元数据
    AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
    // 获取当前正在扫描的类的元数据
    ClassMetadata classMetadata = metadataReader.getClassMetadata();
    // 获取当前类资源(类的路径)
    Resource resource = metadataReader.getResource();
    // 获取类名
    String className = classMetadata.getClassName();
    
    // 如果类名包含 er 就加入到容器中
    return className.contains(RULES);
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微服务 Gateway 的基本配置

    这样当我们访问 http://localhost:8001/payment/get/1 时其实和 http://localhost:9527/payment/g...

    wsuo
  • VMware虚拟机没有网络

    其中:桥接、NAT能够满足虚拟机连接外网的需求,而仅主机模式则不能连接外网,但是能实现与物理机之间的通信。

    wsuo
  • 计算机网络总结 8800字

    1-07 internet(互联网):通用名词,泛指由多台计算机网络互连而成的网络,协议无特指。Internet(因特网):专用名词,特指采用 TCP/IP 协...

    wsuo
  • [javaSE] 注解-自定义注解

    ④ 成员类型是受限的包括原始类型,及String Class Annotation Enumberation

    陶士涵
  • Groovy-11.注解

    一个方法可以有多个注解,此时可以定义一个元注解,将多个注解集中在一起,用AnnotationCollector来定义注释的集合:

    悠扬前奏
  • 注解总结

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yHq0F5VV-1584750416842)(img/@Override底层注解...

    用户7073689
  • Java 进阶巩固:什么是注解以及运行时注解的使用

    这篇文章 2016年12月13日星期二 就写完了,当时想着等写完另外一篇关于自定义注解的一起发。结果没想到这一等就是半年多 - -。 有时候的确是这样啊,总想着...

    张拭心 shixinzhang
  • Java编程之反射中的注解详解

    “注解”这个词,可谓是在Java编程中出镜率比较高,而且也是一个老生常谈的话题。我们之前在聊Spring相关的东西时,注解是无处不在,之前我们简单的聊过一些“注...

    lizelu
  • java注解及在butternife中的实践和原理

    1. 背景 之前去一个公司,说到了java的注解,问java的注解有几种方式,然后我提到了android中的butternife和afinal注解工具,我们知道...

    xiangzhihong
  • Java注解

     自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分。Annotion(注解)是一个接口,程序可以通过反射来获取指定程序元素的Annot...

    xiangzhihong

扫码关注云+社区

领取腾讯云代金券