查看Spring中的@AliasFor的文档,英文描述如下:
Usage Scenarios
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.
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.
下面对每个进行理解并测试
一、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
意思是注解中的属性可以互相为别名进行使用
验证代码:
//定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAliasAnnotation {
@AliasFor(value = "location")
String value() default "";
@AliasFor(value = "value")
String location() default "";
}
//编写测试类
public class MyClass {
@MyAliasAnnotation(location = "这是值")
public static void one(){
}
@MyAliasAnnotation(value = "这是值")
public static void one2(){
}
}
//编写测试代码
public class MyClassTest {
@Test
public void test1() throws NoSuchMethodException {
Consumer<MyAliasAnnotation> logic = a -> {
Assert.assertTrue("", "这是值".equals(a.value()));
Assert.assertTrue("", a.value().equals(a.location()));
};
MyAliasAnnotation aliasAnnotation = AnnotationUtils.findAnnotation(MyClass.class.getMethod("one"), MyAliasAnnotation.class);
logic.accept(aliasAnnotation);
MyAliasAnnotation aliasAnnotation2 = AnnotationUtils.findAnnotation(MyClass.class.getMethod("one2"), MyAliasAnnotation.class);
logic.accept(aliasAnnotation2);
}
}
测试结果截图
二、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相似的功能
验证代码:
//编写元注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AnnotaionBase {
String value() default "";
}
//编写子注解,其中子注解打上了元注解@AnnotaionBase标识
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@AnnotaionBase
public @interface AnnotationChild {
@AliasFor(annotation = AnnotaionBase.class, attribute = "value")
String extendValue() default "";
}
//编写测试类
@AnnotationChild(extendValue = "extendValue")
public class ExtendClass {
}
//编写测试代码
public class ExtendAnnotationTest {
@Test
public void test() throws NoSuchMethodException {
AnnotaionBase annotaionBase = AnnotatedElementUtils.findMergedAnnotation(ExtendClass.class, AnnotaionBase.class);
Assert.assertTrue("", annotaionBase.value().equals("extendValue"));
}
}
测试结果截图
其中要注意的是这里要使用AnnotatedElementUtils,如果还是用AnnotationUtils会发现继承不起作用,这个在AnnotationUtils类的英文文档中也有说明:
在这里也说明了看文档的重要性,往往很多坑在文档里会有特别说明
三、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.
简略意思是注解中使用了元注解时,可以对元注解的值进行重写,并且可用多个不同的别名进行重写(其实就是一和二的结合)
验证代码:
//编写元注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AnnotaionBase {
String value() default "";
}
//编写子注解,其中子注解打上了元注解@AnnotaionBase标识
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@AnnotaionBase
public @interface AnnotationChildMutilAttribute {
@AliasFor(annotation = AnnotaionBase.class, attribute = "value")
String extendValue1() default "";
@AliasFor(annotation = AnnotaionBase.class, attribute = "value")
String extendValue2() default "";
}
//编写测试类
public class ExtendMutilClass {
@AnnotationChildMutilAttribute(extendValue1 = "extendValue1")
public static class extendValue1{
}
@AnnotationChildMutilAttribute(extendValue2 = "extendValue2")
public static class extendValue2{
}
}
//编写测试代码
public class ExtendAnnotaionMutilAttributeTest {
@Test
public void test(){
AnnotationChildMutilAttribute mergedAnnotation1 = AnnotatedElementUtils.findMergedAnnotation(ExtendMutilClass.extendValue1.class, AnnotationChildMutilAttribute.class);
Assert.assertTrue(mergedAnnotation1.extendValue1().equals("extendValue1"));
Assert.assertTrue(mergedAnnotation1.extendValue2().equals("extendValue1"));
AnnotationChildMutilAttribute mergedAnnotation2 = AnnotatedElementUtils.findMergedAnnotation(ExtendMutilClass.extendValue2.class, AnnotationChildMutilAttribute.class);
Assert.assertTrue(mergedAnnotation2.extendValue1().equals("extendValue2"));
Assert.assertTrue(mergedAnnotation2.extendValue2().equals("extendValue2"));
}
}
测试结果截图