Spring @AliasFor 的三种用法,亲测可用,包含测试代码

查看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"));
    }
}

测试结果截图

 

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值