2014-05-07 29 views
2

我想記錄來自類的列表(可能屬於不同的包)的所有方法。請注意,這些方法只能屬於指定的類。AspectJ切入點類的列表中的所有方法

我試過以下,但是這些不工作

(1)如果使用()切入點 在這裏,我得到一個錯誤的切入點和AOP的

"incompatible number of arguments to pointcut, expected 1 found 0" 

@Pointcut("execution(*.*(..)) && if()") 
public static boolean mycut(JoinPoint jp) { 
    boolean matches = ... ;//Test using jp if the declaring class belongs to the list 
    return matches; 
} 

(2)使用組合。 XML 在這裏,我得到一個錯誤

java.lang.NoSuchMethodError: 
com.mypackage.TraceAspect.aspectOf()Lcom/df/jc/aspect/TraceAspect; 

//in com.mypackage.TraceAspect aspect class 
@Pointcut("execution(*.*(..)) && !within(com.mypackage.TraceAspect)") 
public void mycut(){ 
} 

//in aop.xml 
<weaver> 
    <include within="package1.Class1"> 
    <include within="package2.Class2"> 
    <include within="package3.Class3"> 
</weaver> 

這是怎麼回事錯在這裏?

它當然可以通過在切入點中單獨指定每個類來完成,但是這對於數百個類是不可縮放的。理想情況下,如果可以從外部文本文件中拾取類別列表(爲便於配置),這將是非常好的(爲了便於配置)

+0

找到了這個解決方案,但它仍然能夠從aop.xml以外的外部文件中獲取所需的類。http://stackoverflow.com/questions/18130336/read-aspectj-pointcut-definition -from-property-file-for-ltw – user3613747

+0

爲什麼? aop.xml不夠外部?順便說一句,如果你有數百個類,他們中的很多應該有一些共同之處:類名前綴/後綴,包名稱,實現的接口,標記註釋。有許多方法可以重構代碼,以便更容易地表達簡短的切入點,而不是維護容易出錯且通常過時的列表,其中包含數百個條目。 AOP並不意味着要修補糟糕的應用程序設計。恕我直言,你希望這樣做的方式是一個症狀,而不是問題的根源。 – kriegaex

+1

這是一個基於現實世界的要求 - 並非所有的代碼都是很好的代碼:\t 1)源代碼中有許多軟件包(我想要的方面)與一些其他專有Jars中的軟件包重疊我不想在這方面)。 2)代碼是遺留的,寫了很多年,有很多用戶 - 所以重構是沒有問題的 3)有人可能會爭論編寫一個預處理器,將類列表轉換爲aop.xml,但是這會引入兩個額外的步驟 - a)運行預處理器b)將aop.xml放在正確的類路徑中 4)只需在最後尋找一個簡單的解決方案 – user3613747

回答

1

至於您的最後一條評論:我不會讓任何東西感到沮喪,鼓勵你做正確的事情:重構,不要讓生活變得比必要更難。你甚至不知道AspectJ的語法基礎知識,但你已經想要實現一個過度複雜的場景與噸類,這是一個維修的噩夢。我試圖通過激勵你不要做出短視的決定來提供幫助。相信我,我一直在使用AspectJ多年,在你稱之爲具有大量遺留代碼的現實生活項目中。避免即使是最便宜的重構比進行智能重構要昂貴得多 - 根據童子軍規則,不要太多,但足夠了:讓營地比你發現的更乾淨。它付出代價,相信我。

無論如何,談論你的代碼片段:

  • execution(*.*(..))在語法上是錯誤的,因爲你沒有指定返回類型(或佔位符吧)爲要匹配的方法。您想使用execution(* *.*(..))或簡寫版execution(* *(..))
  • 錯誤「切入點的參數數量不兼容,預計發現0」不是來自您的切入點,而是來自您甚至沒有打擾過的建議。你一定寫了類似@Before("mycut()")的東西,但是正確的是@Before("mycut(jp)")

說了這麼多,下面是一個簡單的,完全獨立的,可編譯例子:

驅動程序:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
     System.out.println(multiply(3, add(4, 5))); 
    } 

    public static int multiply(int i, int j) { return i * j; } 
    public static int add(int i, int j) { return i + j; } 
} 

看點:

package de.scrum_master.aspect; 

import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 

@Aspect 
public class TraceAspect { 
    @Pointcut("execution(* *(..)) && if()") 
    public static boolean hasMatchingSignature(JoinPoint thisJoinPoint) { 
     return !thisJoinPoint.getSignature().getName().equals("main"); 
    } 

    @Before("hasMatchingSignature(thisJoinPoint)") 
    public void myAdvice(JoinPoint thisJoinPoint) { 
     System.out.println(thisJoinPoint); 
    } 
} 

樣品輸出:

execution(int de.scrum_master.app.Application.add(int, int)) 
execution(int de.scrum_master.app.Application.multiply(int, int)) 
27 

如果您if()切入點將只返回true,輸出也將顯示的main執行。

+0

+1,但我不得不說,你的鼓勵聽起來更像是鞭打。建議(aspectL):請在下次考慮更好的字眼;-) – A4L

+1

謝謝@ A4L,我聽說過你,並沒有採取任何冒犯行動。我知道我有時可能有點生硬,但實際上OP已經找到了解決方法,如何外化他的班級列表(通過pom.xml,即根據需要的外部文件),但卻不滿足於此,上帝知道爲什麼。 pom.xml *是一個外部文件,甚至是人類可讀的文本。添加/刪除類名是最微不足道的。爲什麼它必須進一步外化?益處或附加層的間接性在哪裏?無論如何,我應該停下來。 – kriegaex

+0

感謝您的全面回答 – user3613747

相關問題