2017-06-06 74 views
0

我從GenericServlet派生並使用@Tx註釋派生類。我想在servlet啓動過程中使用GenericServlet.init()方法來通過aop觸發Servlet外部的一些初始化。前兩行完全不匹配,第三行顯然與所有的servlet匹配,並且第四行匹配所有servlet,儘管使用註釋來指定目標。AspectJ:匹配帶註釋的子類實例的GenericServlet.init()調用

@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。現在的問題是:這是什麼廢話?我該如何禁用它?

回答

0

發現那些com.sun.proxy。當父類加載器已經定義了相同的類/註釋時,類加載器正在使用$ Proxy實例。因爲我想編織像javax.servlet.GenericServlet這樣的系統類,所以我需要使用父類加載器(即使用Jetty本身)加載我的註釋/方面。將我的webapp的註解依賴項設置爲「提供」的maven範圍解決了這個問題。

「已解決」意味着:註釋的代理仍然存在,但現在調用「isAnnotationPresent」實際返回true而不是false,這是AspectJ未能在運行時識別註釋切入點的原因。