目录

一、@AliasFor注解概览

1、对于@AliasFor注释的翻译说明:

Explicit aliases within an annotation.

Explicit alias for attribute in meta-annotation.

Implicit aliases within an annotation.

二、@AliasFor源码属性说明

1、value属性

2、attribute属性

3、annotation属性

三、@AliasFor的使用场景

四、使用举例

1、指定别名,属性互换

①、代码举例

②、使用说明

③、 Spring中的@RequestMapping注解

2、在注解中隐示标明属性的别名

①、代码举例

3、在注解上声明了另一个注解,对另一个注解的属性进行别名覆盖

①、代码举例

②、使用说明

③、Spring中的@Configuration注解

4、组合多个注解,达到通过一个注解使用多个注解的效果

①、代码举例

②、Spring中的@SpringBootApplication注解

五、使用@AliasFor的好处


一、@AliasFor注解概览

1、对于@AliasFor注释的翻译说明:

Explicit aliases within an annotation.

within a single annotation, @AliasFor can be declared on a pair of attributes to signal that they are interchangeable aliases for each other.

意思是注解中的属性可以互相为别名进行使用。

Explicit alias for attribute in meta-annotation.

if the annotation attribute of @AliasFor is set to a different annotation than the one that declares it, the attribute is interpreted as an alias for an attribute in a meta-annotation (i.e., an explicit meta-annotation attribute override). This enables fine-grained control over exactly which attributes are overridden within an annotation hierarchy. In fact, with @AliasFor it is even possible to declare an alias for the value attribute of a meta-annotation.

意思是注解中使用了元注解时,可以对元注解的值进行重写,目的是为了能达到和类继承中override相似的功能。

Implicit aliases within an annotation.

if one or more attributes within an annotation are declared as attribute overrides for the same meta-annotation attribute (either directly or transitively), those attributes will be treated as a set of implicit aliases for each other, resulting in behavior analogous to that for explicit aliases within an annotation.

意思是注解中使用了元注解时,可以对元注解的值进行重写,并且可用多个不同的别名进行重写,达到组合使用的效果。

二、@AliasFor源码属性说明

package org.springframework.core.annotation;import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface AliasFor {@AliasFor("attribute")String value() default "";@AliasFor("value")String attribute() default "";Class<? extends Annotation> annotation() default Annotation.class;
}

1、value属性

用于声明别名关系的目标注解属性名称。例如,如果我们在一个注解中使用@AliasFor注解,同时将value属性设置为另一个注解的属性名称,则这两个属性将被视为别名。

2、attribute属性

该属性与value属性类似,用于声明别名关系的目标注解属性名称。通常情况下,attribute属性与value属性的作用是相同的。

3、annotation属性

该属性用于用于指定别名的注解类型。如果没有指定annotation属性,则默认为当前注解的类型。

三、@AliasFor的使用场景

  • 在注解中一对属性上通过声明@AliasFor,进行属性互换。

  • 在注解中隐示标明属性的别名。

  • 在注解上声明了另一个注解,对另一个注解的属性进行别名覆盖(也可以理解为将一个注解上的属性值传递给另一个注解)。

  • 组合多个注解,达到通过一个注解使用多个注解的效果。

在注解中一对属性上通过声明@AliasFor,进行属性互换构成别名对的每个属性都应该用@AliasFor注释,并且属性或值必须引用该对中的另一个属性。单从技术上看的话,从Spring Framework 5.2.1开始,允许只注释别名对中的一个属性,但是,建议在别名对中对这两个属性进行注释,以获得更好的文档以及与Spring Framework早期版本的兼容性。

四、使用举例

1、指定别名,属性互换

①、代码举例

这里定义了一个@MyAnnotation注解,其中value属性和name属性相互为别名,desc属性为普通属性。使用该注解时,可以使用value属性或者name属性设置注解的值。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {@AliasFor("name")String value() default "";@AliasFor("value")String name() default "";String desc() default "";
}
@MyAnnotation(name = "myName", desc = "myDescription")
public class MyClass {// ...
}

在这个例子中,@MyAnnotation(name = "myName", desc = "myDescription")和@MyAnnotation(value = "myName", desc = "myDescription")是等价的。

②、使用说明

  • 必须以属性别名对的形式出现,即要求有两个属性,且这两个属性的名字分别为对方别名。

  • 这两个属性的必须拥有相同的返回值类型。

  • 这两个属性必须拥有相同的默认值。

  • @AliasFor中的annotation()不应该被指定值。

③、 Spring中的@RequestMapping注解

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};
}

2、在注解中隐示标明属性的别名

①、代码举例

比如,Spring中的@Bean注解,我们在使用时这个注解时,可以直接填写内容,而不用主动指定"name"和"value"属性,从而达到了隐示表明属性别名的效果。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {@AliasFor("name")String[] value() default {};@AliasFor("value")String[] name() default {};/** @deprecated */@DeprecatedAutowire autowire() default Autowire.NO;boolean autowireCandidate() default true;String initMethod() default "";String destroyMethod() default "(inferred)";
}
@Configuration
public class MyConfiguration {@Bean("myBean")public MyBean myBean() {return new MyBean();}
}

3、在注解上声明了另一个注解,对另一个注解的属性进行别名覆盖

①、代码举例

我们有一个注解@MyAnnotation,我们想要为它定义一个别名注解@MyAliasAnnotation,可以这样定义:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {@AliasFor("name")String value() default "";@AliasFor("value")String name() default "";String desc() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MyAnnotation
public @interface MyAliasAnnotation {@AliasFor(annotation = MyAnnotation.class, attribute = "value")String name() default "";
}

在这个例子中,@MyAliasAnnotation被标记为别名注解,它使用了@MyAnnotation的属性value作为自己的name属性的别名。其中annotation属性指定了原注解的类型,attribute属性指定了要使用的属性名称。

②、使用说明

  • 在需要override的注解的属性上使用:@AliasFor(annotation="元注解",attribute="元注解的属性")。

  • 被标记@AliasFor的属性和atttibute所指向的元注解属性必须有相同的返回值类型。

  • @AliasFor中annotation指向的元注解必须作用于正在定义的注解上(就是要标记在新注解上)。

③、Spring中的@Configuration注解

package org.springframework.context.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";
}

可以看出对于value这个属性来说,@Configuration注解中的值会重写@Component的value属性值,这有点像类之间的继承,子类可以重父类的方法。我们也可以将@Configuration注解看成@Component的子注解。

当然,你也可以理解为将一个注解上的属性值传递给另一个注解,我个人更习惯采用这种理解,因为后续可以通过一个注解组合多个注解进行使用,通过一个注解将值传递给多个注解,而这与java的继承的概念并不相同。

4、组合多个注解,达到通过一个注解使用多个注解的效果

①、代码举例

假设我们有三个注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {String value();
}@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {String name();
}@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {String desc();
}

我们可以使用@AliasFor注解来定义一个新注解,将这三个注解组合起来,具体代码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@MyAnnotation1
@MyAnnotation2
@MyAnnotation3
public @interface MyCombinedAnnotation {@AliasFor(annotation = MyAnnotation1.class, attribute = "value")String value() default "";@AliasFor(annotation = MyAnnotation2.class, attribute = "name")String name() default "";@AliasFor(annotation = MyAnnotation3.class, attribute = "desc")String desc() default "";
}

在这个新注解中,我们使用了@AliasFor注解,将MyAnnotation1中的value()方法和MyAnnotation2中的name()方法都映射到MyCombinedAnnotation中的value()方法中,同时将MyAnnotation3中的desc()方法映射到MyCombinedAnnotation中的desc()方法中。

这样,我们就可以通过一个注解来使用这三个注解的属性了。例如:

@MyCombinedAnnotation(value = "hello", name = "world", desc = "this is a combined annotation")
public class MyClass {//...
}

上面的代码等价于以下的代码:

@MyAnnotation1("hello")
@MyAnnotation2(name = "world")
@MyAnnotation3(desc = "this is a combined annotation")
public class MyClass {//...
}

注意,我们需要在MyCombinedAnnotation中加上@MyAnnotation1、@MyAnnotation2、@MyAnnotation3三个注解,表示这个新注解中包含了这三个注解的所有属性,可以通过@MyCombinedAnnotation来代替这三个注解的使用。同时,在MyCombinedAnnotation中定义的属性,需要使用@AliasFor注解来映射到MyAnnotation1、MyAnnotation2、MyAnnotation3中的对应属性。

②、Spring中的@SpringBootApplication注解

@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 = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};@AliasFor(annotation = ComponentScan.class,attribute = "nameGenerator")Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

五、使用@AliasFor的好处

使用@AliasFor注解可以为注解元素之间建立关联,提高注解的可读性和可维护性。具体好处如下:

  1. 简化注解定义:通过@AliasFor注解,可以简化注解定义中的元素声明,减少了重复代码,提高了代码的可读性和可维护性。

  2. 避免冗余:通过@AliasFor注解,可以将重复的注解元素关联起来,避免了冗余的元素声明,使代码更加简洁。

  3. 保持一致性:通过@AliasFor注解,可以将注解元素之间的关系明确化,保持注解的一致性,提高代码的可读性和可维护性。

  4. 明确注解元素的作用:通过@AliasFor注解,可以明确注解元素之间的关系,帮助开发人员更好地理解注解的作用和用法,提高开发效率和代码质量。

@AliasFor的使用方法相关推荐

  1. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群

    作者:Jeffrey Hunter 了解如何以低于 2,700 美元的费用在 Oracle Enterprise Linux 上安装并配置 Oracle RAC 11g 第 2 版开发集群. 本指南中 ...

  2. Java面试题大全2021版

    一.Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Run ...

  3. SpringBoot之Listener注册到Spring容器中的多种方法

    相关文章: SpringBoot 之AOP切面的使用 SpringBoot之Interceptor拦截器注入使用 SpringBoot之Filter过滤器的实现及排序问题 SpringBoot 之多个 ...

  4. Spring中@AliasFor注解的作用及原理

    本文基于Springboot 2.1.6.RELEASE 版本分析. 关于@AliasFor注解,曾提过的一个issue Explicit attribute overrides configured ...

  5. 从配置Druid,学习@ConfigurationProperties注解方法

    约定大于配置 我们知道Springboot的思想就是约定大于配置的思想,所以很多地方都是JavaConfig的模式: JavaConfig就是使用注释来描述Bean配置的组件.JavaConfig 是 ...

  6. java中@AliasFor注解

    Java中的@AliasFor注解,是Spring框架的一个元注解,用于指定注解的别名关系.它可以用于定义同一个注解的多个属性之间的别名关系,让它们在使用时可以互相替代. 使用@AliasFor注解的 ...

  7. Kotlin协程使用,协程使用注意事项,协程中的await方法使用|不使用suspend使用协程

    参见 码云 协程使用方法一 (Dispatchers调度器模式) 指定不同线程.同线程会挂起并阻塞(挂起是不影响主线程执行,阻塞是同样的IO线程会阻塞) withContext(Dispatchers ...

  8. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  9. IDEA自动生成对象所有set方法

    idea中有一款插件能够生成对象所有的set方法,GenerateAllSetter :下载地址 步骤1:将下载好的压缩包放在自己记得的文件夹中,在idea中进行导入 步骤2:在本地选中刚才的压缩包, ...

最新文章

  1. 分布式多层次限流概述
  2. pyplot绘图标题错误处理
  3. duration java_Java Duration类| minusMinutes()方法与示例
  4. python中max函数用法_python奇技淫巧——max/min函数的用法
  5. 学习Jsoup(二)
  6. 方正电脑如何关闭网络启动计算机,方正电脑怎么进安全模式
  7. Visio图片加全边框
  8. 航空航天等军工研究所
  9. 被遗忘的艺术:图的思维方式
  10. 关于计算机未来理想,关于未来与梦想的作文
  11. 能力素质有所欠缺_除了岗位培训,能力的培训也十分关键
  12. 最让人舒服的11种颜色RGB值和十六进制值
  13. RCC目前最近技术与今后发展
  14. Arcgis小技巧【1】——地理配准
  15. 【转】由滤波器系数绘制尺度函数和小波函数图像的Matlab程序
  16. 如何裁剪视频画面尺寸?快把这些方法收好
  17. 提高网络泛化能力,过拟合
  18. Keras CIFAR-10彩色图像物体识别 卷积神经网络
  19. 在线购物飞涨。 这就是它不会持续的原因
  20. 用AidLux跑老人摔倒检测项目,看AI助老轻松落地

热门文章

  1. C#联合halcon开发框架源码
  2. 日常生活中该如何预防腰椎病呢?
  3. 基于ETest和模块化平台的应答器传输系统测试工装的设计与实现
  4. 我怀疑你在我身上按了监控,考研狗的真实现状
  5. 进程同步,进程互斥【操作系统学习笔记】
  6. 一键定制rom刷机包!好用工具
  7. 天马8.4寸国产工业液晶屏TM084SDHG02详细资料
  8. 文件下载后端返回base64文件流,使用a标签下载
  9. excel修改柱状图系列1名称
  10. Composer加速镜像,一些小技巧