控制器初始化时修改了自己以及父类控制器方法上的注解中的值,但是切面中获取时,父类方法上的注解中的值还是修改前的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
persona5
V2EX    程序员

控制器初始化时修改了自己以及父类控制器方法上的注解中的值,但是切面中获取时,父类方法上的注解中的值还是修改前的

  •  
  •   persona5 2021-05-27 16:32:56 +08:00 1657 次点击
    这是一个创建于 1599 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求上 MyController 中不需要重写父类中方法的逻辑,仅仅注解中 testField 的值不是默认值。

    因为不想仅仅为了指定下 testField 而去重写多个方法,所以考虑字类初始化的时候,批量修改 testField 。

    但是请求接口的时候,通过观察切面中的日志输出,子类中非重写的方法 method3 的注解对象中的 testField 是被修改为了 test2 ;而请求接口 method1 、method2 的时候,testField 还是 test1,并且切面中输出的注解对象的地址与 static 代码块中输出的不同。

    Spring 的 AOP,注解、反射工具类是 hutool 的。

    // 注解 @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface MyAnnotation { String testField() default "test1"; } // 抽象控制器 public abstract class AbstractController{ @MyAnnotation @RequestMapping(value = "method1", method = RequestMethod.GET) public RestfulResponse<Boolean> method1() { return new RestfulResponse<>(true); } @MyAnnotation @RequestMapping(value = "method2", method = RequestMethod.GET) public RestfulResponse<Boolean> method2() { return new RestfulResponse<>(true); } } // 继承抽象控制器 @RestController public class MyController extends AbstractController { static { for (Method method : ReflectUtil.getMethods(MyController.class)) { if (AnnotationUtil.hasAnnotation(method, MyAnnotation.class)) { MyAnnotation annotation = AnnotationUtil.getAnnotation(method, MyAnnotation.class); AnnotationUtil.setValue(annotation, "testField", "test2"); // 输出 annotation 地址 } } } @MyAnnotation @RequestMapping(value = "method3", method = RequestMethod.GET) public RestfulResponse<Boolean> method3() { return new RestfulResponse<>(true); } } // 切面 @Aspect public class MyAspect implements Ordered { @Around("@annotation(myAnnotation)") public Object around(ProceedingJoinPoint pjp, MyAnnotation myAnnotation) throws Throwable { // 输出 myAnnotation 地址、testField 值 return pjp.proceed(); } } 

    请问是那里出了问题,为什么切面中获取到的注解对象和 static 中的不是同一个?

    5 条回复    2021-05-28 10:15:29 +08:00
    ChovyChu
        1
    ChovyChu  
       2021-05-27 16:45:44 +08:00
    知识盲区,坐等大神。

    个人感觉可能是顺序问题导致被 default 值覆盖了?
    MoHen9
        2
    MoHen9  
       2021-05-27 18:38:22 +08:00   1
    不太了解 spring aop 是个什么机制,debug 了一下,发现注入的 MyAnnotation 的实例和通过反射获取的实例是两个不同对象

    Method method = ((MethodSignature) pjp.getSignature()).getMethod();
    MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);

    通过反射获取的 annotion 实例是你想要的,而注入的实例似乎好像大概差不多是在初始化时就缓存好了的。解决问题比较简单,背后的原理什么的,只有坐等大神解答一下了。
    nulIptr
        3
    nulIptr  
       2021-05-27 18:59:04 +08:00
    没想明白,什么场景下才运行时修改注解里面属性的值?这跟我理解的注解用途不太一样啊。。。
    persona5
        4
    persona5  
    OP
       2021-05-27 21:46:01 +08:00
    @MoHen9 感谢,我也测试一下看看。


    @nulIptr 原因我在开头说了,不想仅仅为了指定下 testField 而去重写多个方法。
    MyAnnotation 中 testField 的默认值是 test1 对吧,我在 MyController 中需要只用 @MyAnnotation(testField = "test2") 的注解,既需要指定 testField 为 test2 。但是接口方法内的逻辑又没有需要修改的地方,不修改注解中 testField 的值的话。MyController 中就要重写 method1 、method2 了,重写仅仅为了去加上 @MyAnnotation(testField = "test2") 这个注解。
    nulIptr
        5
    nulIptr  
       2021-05-28 10:15:29 +08:00
    @persona5 我认为你说的这种场景就应该用虚方法 override,注解就是编译期添加的额外信息,你还在运行时给改了,我觉得是在挖坑。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     869 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 22:29 PVG 06:29 LAX 15:29 JFK 18:29
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86