檢視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"));
}
}
測試結果截圖