2011-08-24 41 views
12

我怎麼能編寫適用於方法執行其控裝置,帶註釋的接口方法的AspectJ切入點?例如:@AspectJ切入點的方法是與註釋覆蓋的接口方法

interface A { 
    @MyAnnotation void method(); 
} 
class B implements A { 
    void method(); 
} 

切入點execution(@MyAnnotation * *.*(..))不只有B.method()進行註釋本身相匹配。有沒有另一種方法來做到這一點?

回答

10

正如尼古拉斯指出,這是不可能的AspectJ中。這就是爲什麼它是不可能更加證明(從http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html部分標註繼承和切入點匹配拍攝):

根據Java 5規範,非類型的註解不被繼承,並在註釋類型只如果他們有@Inherited元註釋,則繼承。到c2.aMethod調用(這將在您的例子來弘())是不匹配的,因爲加入了修飾語點匹配(能見度修飾符,註釋和throws子句)是基於連接點的主體(方法實際上被稱爲)。

在遭受同樣的問題之後,我寫了一個小的方法/庫,允許您爲這些方法編寫切入點。下面是它如何爲你工作,例如:

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

OR

myAnnotationIsExecuted(): execution(public * A+.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

方法implementsAnnotation(String,JoinPoint)從庫中來;一個檢查實現的方法是否包含指定註釋的基本方法。

有關方法/庫

的更多信息可以發現here.

3

更新

由於看來,它不能在春季(見原來的答案)我會說,你需要將註釋添加到每個方法的實現類來完成。有一個明顯的方式做到這一點,但我想,如果你正在尋找一種更自動的方式,你需要自己寫一個。

我能想象某種土生土長的後處理器將尋找一個特定的註解,可以說@ApplyThisAnnotationToAllWhoInheritMe。一旦找到這個註解,它會掃描源代碼以繼承成員,並在編譯發生之前在需要的地方添加所需的註釋。

無論如何,如果你正在使用Spring AOP要做到這一點,似乎它需要對實施者方法。如果你希望得到的這些類將幫助你超出你的控制範圍,你可能需要編寫自己的Spring AOP工具。

原來的答案

Spring 3.0 Documentation

AspectJ允許在接口上註解是不能繼承Java的規則。

我發現部分7.8.2 Other Spring aspects for AspectJ此位,這是7.8 Using AspectJ with Spring applications的一部分,這讓我覺得這是一個全球性的規則。

+0

感謝;這解釋了爲什麼我的切入點不起作用。但是,我正在尋找一個有效的工具。 :-) –

+0

@hstoerr:編輯完問題後,我編輯了我的答案。讓我知道它是否仍然不可接受。 –

+1

春天的文檔實際上並沒有說它不可能匹配我想要的東西 - 只是我嘗試的簡單方法不起作用。在Aspectj中可能會出現一些我無法想到的奇怪的事情。所以我仍然希望。 :-) –

2
//introducing empty marker interface 
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker; 

public pointcut p1() : execution(* TrackedParentMarker+.*(..)); 

此外,您應該啓用-XhasMember編譯器標誌。

+0

不幸的是,這並不完全。它適用於實現一個接口的所有類的每個方法,該接口至少有一個攜帶註釋的方法。但它應該只應用於使用該標記實現接口方法的一種方法。或者至少與標記的接口方法具有相同名稱的方法,如果可以在AspectJ中說。 –