在业务层拦截器里无法获取注解的问题

很奇怪的问题:

1、定义了一个注解,主要用于Method

2、在Service的Method上添加注解

3、对Service通过Enhancer.enhance()进行增强

4、在Config中通过addGlobalServiceInterceptor添加业务层拦截器

5、在拦截器中获取Method的注解:

    public void intercept(Invocation inv) {
        Method method = inv.getMethod();
        Annotation[] annos = method.getAnnotations();
        System.out.println(annos.length);
    }

问题就出在上面,有的Method明明有注解,却返回空数组

调试跟踪inv返回的method,发现其中的annotations是空的

事实上这个method确实有注解。。。

但并不是所有的都返回空数组,有的Service确实能返回

仔细比较过两个Method,调用的都是同样的注解

直接懵比了


以下是定义注解的方法:

    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD })


不知道还有什么原因能引起这种情况,进过坑的老铁快支支招

评论区

JFinal

2018-04-29 10:19

这个可能是有一个没有 Enhancer.enhance(...),建议单步调试一下,看看 inv.getTarget() 获取的对象是不是被 enhance 过的,一目了然

netwild

2018-04-29 15:37

@JFinal
试过了,inv.getTarget()获取的对象确实是enhance过的
诡异的是,只是访问一次,同一个Method却被拦截了两次
第一次被拦截时获取的Anno是空数组,第二次却能返回正确的Anno数组


@Override
public void intercept(Invocation inv) {

Object target = inv.getTarget();
Class targetClazz = target.getClass();
System.out.println(" ---> targetClazz:" + targetClazz.getName());

Method method = inv.getMethod();
Class methodClazz = method.getDeclaringClass();
System.out.println(" ---> methodClazz:" + methodClazz.getName());

Annotation[] annos = method.getAnnotations();
System.out.println(" 注解:" + annos.length);

inv.invoke();
}


控制台输出:

---> targetClazz:itez.plat.base.service.CompService$$EnhancerByCGLIB$$7f7135d3
---> methodClazz:itez.plat.base.service.CompService
注解:0
---> targetClazz:itez.plat.base.service.CompService$$EnhancerByCGLIB$$7f7135d3
---> methodClazz:itez.plat.base.service.CompService
注解:1

JFinal action report -------- 2018-04-29 15:28:17 ------------------------------
Url : GET /plat/login
Controller : itez.plat.base.controller.IndexController.(IndexController.java:1)
Method : login
Parameter : from=http://localhost/www/plat
--------------------------------------------------------------------------------
15:28:17.403 INFO ELog 完成渲染视图(2ms):/common/temp/login.html


单步调试时,两次被拦截的方法看起来一模一样
区别就是第一次无法返回Anno数组,而第二次却能返回
@JFinal

netwild

2018-04-30 11:12

找到原因了,原来是被enhance的method里调用了super的method
然后super的method也被enhance了
因为super没加anno,所以获取不到
但还是不理解在Interceptor中,通过inv获得的method显示的还是子类的

JFinal

2018-04-30 11:26

@netwild 找到原因就好解决了,再调试追下去,找到真正的 target 中的 Method ,然后获取注解

热门反馈

扫码入社