Spring 框架提供了很丰富的注解可以让我们很方便的进行 Spring 配置,今天要讲的注解——@AliasFor之前你可能并没有关注过,因为平时开发时我们的确不太会用到。

我关注到这个注解是因为我经常翻看 Spring 的源代码,在 Spring 提供的注解中大量的用到了这个注解,对这个注解不熟悉的话会影响你对代码的判断,而且有些代码看的总是似懂非懂的,很难受(强迫症,哈哈),比如说下面这段代码。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication { @AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {}; @AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; @AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true; }

上面的代码大致能“猜测”出 @AliasFor 是为了属性起别名,但是 @AliasFor 的使用场景,使用方式,实现原理是什么?这博客就简单介绍下。

@AliasFor注解的几种使用方式

1. 在同一个注解中显示使用,将注解中的多个属性互相设置别名

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping { @AliasFor("path")
String[] value() default {}; @AliasFor("value")
String[] path() default {}; //...
}

为什么要给 value 属性和 path 属相互相设置别名也是有原因的。我们知道在 Spring 中给 value 属性设置值是可以省略属性的,比如可以写成:

RequestMapping("/foo")

这样写比较简洁,但是这样可读性不高,我们并不知道 value 属性代表什么意思。如果给这个属相设置一个 path 别名的话我们就知道这个是在设置路径。

但是要注意一点,@AliasFor 标签有一些使用限制:

  • 互为别名的属性属性值类型,默认值,都是相同的;
  • 互为别名的注解必须成对出现,比如 value 属性添加了@AliasFor(“path”),那么 path 属性就必须添加@AliasFor(“value”);
  • 另外还有一点,互为别名的属性必须定义默认值。

那么如果违反了别名的定义,在使用过程中就会报错。

2. 给元注解中的属性设定别名

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication { @AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {}; @AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
//...
}

我们来看 @SpringBootApplication 这个注解,这个注解是有其他几个注解“组合”而成的。下面的代码就是在给@ComponentScan 注解的basePackages属性设置别名scanBasePackages。如果不设置attribute属性的话就是在给元注解的同名属性设置别名。

@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};

这种使用方式的好处是可以将几个注解的功能组合成一个新的注解。

@AliasFor 的实现代码

贴大片代码的事就不干了。@AliasFor 的具体实现在AnnotationUtils.findAnnotation 中,代码大家自己翻看吧。


参考

@AliasFor 注解的更多相关文章

  1. 关于如何使用Spring里@AliasFor注解进行注解的封装

    不知道大家每次使用Spring boot的时候有没有看过它启动类里 @SpringBootApplication这个注解呢?众所周知,这个注解是一个复合注解,但是注解是不能继承元注解的属性的,也就是说 ...

  2. @AliasFor注解

    @AliasFor注解 @AliasFor是一个注解,用于为注解属性声明别名. 代码如下:它有两个属性value和attribute @AliasFor注解注释了 自身,并且value和attribu ...

  3. 朱晔和你聊Spring系列S1E9:聊聊Spring的那些注解

    本文我们来梳理一下Spring的那些注解,如下图所示,大概从几方面列出了Spring的一些注解: 如果此图看不清楚也没事,请运行下面的代码输出所有的结果. Spring目前的趋势是使用注解结合Java ...

  4. Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils

    Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils Spring 系列目录(https://www.cnblogs.com/binary ...

  5. Spring @AliasFor

    原文地址:https://blog.csdn.net/wolfcode_cn/article/details/80654730 在Spring的众多注解中,经常会发现很多注解的不同属性起着相同的作用, ...

  6. Spring 注解编程之注解属性别名与覆盖

    前两篇文章咱聊了深入了解了 Spring 注解编程一些原理,这篇文章我们关注注解属性方法,聊聊 Spring 为注解的带来的功能,属性别名与覆盖. 注解属性方法 在进入了解 Spring 注解属性功能 ...

  7. 品Spring:能工巧匠们对注解的“加持”

    问题的描述与方案的提出 在Spring从XML转向注解时,为了自身的开发方便,对注解含义进行了扩充(具体参考本号上一篇文章). 这个扩充直接导致了一个问题,就是需要从注解往元注解以及元元注解(即沿着从 ...

  8. 品Spring:注解终于“成功上位”

    历史还是抛弃了XML,当它逐渐尝到注解的甜头之后. 尤其是在Spring帝国,到处充满着注解的气息. 注解从一个提供附属信息的“门客”,蜕变为颇具中流砥柱的“君侯”. 注解成功登上了帝国的舞台,定会像 ...

  9. 跟Evan学Sprign编程思想 | Spring注解编程模式【译】

    Spring注解编程模式 概况 多年来,Spring Framework不断发展对注解.元注解和组合注解的支持. 本文档旨在帮助开发人员(Spring的最终用户以及Spring Framework和S ...

随机推荐

  1. 新来的运维这样用HDFS,CIO都懵了···

    摘要:本文主要研究了HDFS文件系统的读写流程以及基于MRS在windows客户端下读写HDFS文件的实现. HDFS(Hadoop分布式文件系统)是Apache Hadoop项目的一个子项目. HD ...

  2. JavaScript入门-函数function(二)

    JavaScript入门-函数function(二) 递归函数 什么是递归函数? 递归简单理解就是,在函数体里,调用自己. //我们在求一个10的阶乘的时候,可能会这么做 //写一个循环 var to ...

  3. Linux应急响应--入侵排查

    1.入侵者可能会删除机器的日志信息,可以查看日志信息是否还存在或者是否被清空,相关命令示例: ll -h /var/log/*  系统日志一般都存在/var/log下常用的系统日志如下:核心启动日志: ...

  4. 【Problems】MySQL5.7 datetime 默认值设为‘0000-00-00 00:00:00'值出错

    记录 MySQL5.7 datetime 默认值设为'0000-00-00 00:00:00'值出错 我的MySQL版本 mysql --version 5.7.28 C:\Users\x1c> ...

  5. BAPI_GOODSMVT_CREATE的参数GOODSMVT_CODE的说明

    BAPI_GOODSMVT_CREATE 的功能就是用于货物移动,其主要可以实现MB*事物的一些功能,其中该BAPI的参数 GOODSMVT_CODE就控制了对应哪个事物码的功能,下面给出该参数的值和 ...

  6. ubuntu20.04并添加桌面快捷方式,以安装火狐可浏览器开发版(水狐)为例

    @参考原文 1. 下载linux版源文件 从火狐官网下载linux版的水狐源文件压缩包,@火狐浏览器开发版(水狐)下载地址. 2. 解压下载源文件 将下载的"tar.bz2"文件解 ...

  7. IP2723T中文规格书PDF

    IP2723T 是一款集成多种协议.用于 USB 输出端口的快充协议 IC.支持多种快充协议,包括 USBTypeC DFP,PD2.0/PD3.0/PPS,HVDCPQC4/QC4+/QC3.0/Q ...

  8. 两节锂电池充电芯片,和保护IC的接法

    1.两节锂电池的充电电路:可以分为三种方式. 第一种,USB口的5V输入,使用一颗SOT23-6的升压IC,直接升压到8.4V.电流在1A以下.优点是成本最低,缺点是,没有锂电池充电控制逻辑,和锂电池 ...

  9. Py-时间,随机,os,sys,jsonpickle序列化,shelve,xml模块

    内置模块 1.时间模块 第一:time.time()是时间戳 时间戳默认是 从1970年到现在过的秒数,是一个很长的数值它可以做时间的计算以及显示 第二:localtime() 获取当前的时间,按元组 ...

  10. (16)-Python3之--集合(set)操作

    1.定义 集合的关键字:set 集合主要作用: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 集合用大括号{}表示,元素间用逗号分隔. 建立集合类型用{} ...