2014-09-29 160 views
0

我在使用SpringAOP + AspectJ建立日誌記錄方面時遇到了一些麻煩。我希望在使用@Loggable批註註釋類或方法時觸發「Around」方法。以下是我的建議代碼:AspectJ OR運算符似乎不起作用

@Around(value = "execution(* *(..)) && target(bean) && @annotation(loggable)", argnames "bean, loggable") 
public void test1(ProceedingJoinPoint method, Object bean, Loggable loggable) { } 

@Around(value = "execution(* *(..)) && target(bean) && @within(loggable)", argnames "bean, loggable") 
public void test2(ProceedingJoinPoint method, Object bean, Loggable loggable) { } 

@Around(value = "execution(* *(..)) && target(bean) && (@annotation(loggable) || @within(loggable))", argnames "bean, loggable") 
public void test3(ProceedingJoinPoint method, Object bean, Loggable loggable) { } 

test1和test2失火。 test3沒有,這是我真正想要的。任何想法爲什麼這可能是?

回答

1

首先,您的切入點存在語法錯誤。它不是小寫argnames,而是argNames,並且在參數名稱和值之間缺少=。所以它一定是argNames = "bean, loggable"

其次,如果您的建議返回void它只會匹配返回void的方法。更一般的情況是在建議中返回Object以真正匹配所有方法。

最後但並非最不重要的一點,您應該看到一條警告,它解釋了第三個切入點的問題。這顯示在您的Eclipse IDE或AspectJ編譯器的(AJC)日誌輸出:

ambiguous binding of parameter(s) loggable across '||' in pointcut 

這意味着,你不能說「綁定一個值或其他的參數‘爲loggable’」。如果兩個條件匹配會怎樣?哪一個應該分配?你有兩個選擇,假設你的完全合格的類名稱爲de.scrum_master.app.Loggable

A)無參考@Loggable註釋需要:

這是一個簡單的情況。如果@Loggable沒有任何需要讀取的參數,則不需要將其綁定到參數。順便說一句,如果你希望你的切入點也可以捕獲靜態方法,你不應該綁定target(),因爲目標是null。也許在Spring-AOP中,這是無關緊要的,因爲它只適用於Spring Beans,但是在全功能的AspectJ中它會有所作爲,因爲它更強大。

@Around(value = "execution(* *(..)) && (@annotation(de.scrum_master.app.Loggable) || @within(de.scrum_master.app.Loggable))") 
public Object withoutLoggableReference(ProceedingJoinPoint thisJoinPoint) { 
    Object bean = thisJoinPoint.getTarget(); 
    System.out.println(thisJoinPoint + " -> " + bean); 
    return thisJoinPoint.proceed(); 
} 

,或等效:

@Around(value = "execution(* (@de.scrum_master.app.Loggable *.*)(..)) || execution(@de.scrum_master.app.Loggable * *.*(..))") 
public Object withoutLoggableReference(ProceedingJoinPoint thisJoinPoint) { 
    Object bean = thisJoinPoint.getTarget(); 
    System.out.println(thisJoinPoint + " -> " + bean); 
    return thisJoinPoint.proceed(); 
} 

B)參考@Loggable註釋需要:

你沒有其他選擇,而不是兩個單獨的切入點去,如果你要綁定的對參數的註釋。也許你可以使用實用的方法來做實際的日誌記錄,以避免你的建議中的代碼重複。