注解 AliasFor 失效

注解 AliasFor 失效,第1张

注解 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 {

    
    @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成对出现
  • AliasFor 修饰的属性,返回值类型必须相同
  • AliasFor 修饰的属性,必须定义默认值 ,且默认值必须相同
  • 使用工具类 AnnotationUtils 获取注解
  • 不要定义annotation

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5438245.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存