注解 AliasFor 失效

场景

当前controller层的代码,都会使用两层 catch 语句,捕获异常。

		try{
        } catch (AMSException e) {
            result.setResultCode(1);
            result.setErrorDesc(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            result.setResultCode(1);
            result.setErrorDesc("查询,更新失败!");
        }

AMSException 是用户手动抛出的异常,Exception则用于捕获未知异常。于是想全局定义异常处理器,处理异常。 其中AMSExceptionAnnotation 用于处理未知异常的消息提示。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AMSExceptionAnnotation {

    /**
     * 错误信息提示
     *
     * @return
     */
    @AliasFor("msg")
    String value() default "";

    @AliasFor("value")
    String msg() default "";
}
@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/test")
    @AMSExceptionAnnotation(msg = "获取测试接口数据失败!")
    public void test() {
        int i = 1 / 0;
    }
}
AMSExceptionAnnotation amsExceptionAnnotation =handlerMethod.getMethod().getAnnotation(AMSExceptionAnnotation.class);
String errorMsg = "";
if(amsExceptionAnnotation !=null){
	errorMsg = amsExceptionAnnotation.value()
}
原因分析

在测试中发现无法获取到 注解中的信息。百度后,很多人说的是 因为AliasFor 注解需要成对出现,检查后也没问题。后开看了文档,才发现原因:

Like with any annotation in Java, the mere presence of @AliasFor on its own will not enforce alias semantics. For alias semantics to be enforced, annotations must be loaded via the utility methods in AnnotationUtils. Behind the scenes, Spring will synthesize an annotation by wrapping it in a dynamic proxy that transparently enforces attribute alias semantics for annotation attributes that are annotated with @AliasFor. Similarly, AnnotatedElementUtils supports explicit meta-annotation attribute overrides when @AliasFor is used within an annotation hierarchy. Typically you will not need to manually synthesize annotations on your own since Spring will do that for you transparently when looking up annotations on Spring-managed components.

AliasFor 本身不具备特定语义,不是java原生提供的注解。所以原生的获取注解方式,只会把AliasFor 当成普通的注解处理。只用通过 Spring中提供的工具类 AnnotationUtils,才能正确解析AliasFor 语义。

所以修改为如下,即可获取互为别名的属性值。

AMSExceptionAnnotation amsExceptionAnnotation = AnnotationUtils.getAnnotation(handlerMethod.getMethod(), AMSExceptionAnnotation.class);
总结

当然其他的限制也必须满足:

Each attribute that makes up an aliased pair must be annotated with @AliasFor, and either attribute() or value() must reference - the other attribute in the pair.
Aliased attributes must declare the same return type.
Aliased attributes must declare a default value.
Aliased attributes must declare the same default value.
annotation() should not be declared

总结一下就是, 在单个注释中,可以在一对属性上声明@AliasFor,以表明它们互为可互换的别名。且需要满足一下条件,才能获取到互为别名的属性

  • AliasFor中使用 attribute 或者value,必须 成对出现
  • AliasFor 修饰的属性,返回值类型必须相同
  • AliasFor 修饰的属性,必须定义默认值 ,且默认值必须相同
  • 使用工具类 AnnotationUtils 获取注解
  • 不要定义annotation() 。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值