AspectJ:匹配带注释的子类实例

时间:2017-06-06 11:16:50

标签: java aspectj pointcuts

我从GenericServlet派生并用@Tx注释派生类。我想在servlet启动期间使用GenericServlet.init()方法调用来通过aop触发servlet之外的一些初始化。前两行根本不匹配,第三行显然匹配所有servlet,第四行匹配所有servlet,尽管使用注释指定目标。

@Before("@this(com.github.jjYBdx4IL.aop.tx.Tx)
    && execution(* javax.servlet.GenericServlet+.init()) && this(foo)")
@Before("@target(com.github.jjYBdx4IL.aop.tx.Tx)
    && execution(* javax.servlet.GenericServlet+.init()) && this(foo)")

@Before("execution(* javax.servlet.GenericServlet+.init()) && this(foo)")
@Before("target(@com.github.jjYBdx4IL.aop.tx.Tx Object)
    && execution(* javax.servlet.GenericServlet+.init()) && this(foo)")

如果我将GenericServlet + .init()替换为GenericServlet.init(..)

,则第一行有效
@Before("@this(com.github.jjYBdx4IL.aop.tx.Tx) 
    && execution(* javax.servlet.GenericServlet.init(..)) && this(foo)")

这很奇怪,因为使用调试器,GenericServlet.init()肯定会从GenericServlet.init(ServletConfig)调用...

有人可以澄清一下,这里发生了什么?我希望第一行可以解决这个问题,但事实并非如此。

我最好的猜测是它与Jetty实例本身和webapp的类加载器使用的类加载器的分离有关......我设法使下面的内容至少编织了init()方法(根据maspectj的调试输出):

@After("@this(com.github.jjYBdx4IL.aop.tx.Tx
    && target(javax.servlet.GenericServlet+)
    && execution(* init()) && this(foo)")

但它不会触发。

更新

我将问题追溯到:URLClassLoader loads Annotation as com.sun.$Proxy$27

基本上,foo.getClass()。isAnnotationPresent(Tx.class)总是返回false。现在的问题是:这是什么废话?我该如何禁用它?

1 个答案:

答案 0 :(得分:0)

当父类加载器已经定义了相同的类/注释时,类加载器正在使用这些com.sun.proxy。$ Proxy实例。因为我想编织像javax.servlet.GenericServlet这样的系统类,我需要使用父类加载器加载我的注释/方面,即使用Jetty本身。将我的webapp的包含注释的依赖项设置为“提供”的maven范围解决了这个问题。

“Solved”表示:注释的代理仍然存在,但是对“isAnnotationPresent”的调用实际上返回true而不是false,这就是AspectJ无法在运行时识别注释切入点的原因。