2010-08-17 33 views
3

它的方便AOP(如AspectJ中,SpringAOP)來處理(提供諮詢)橫切關注約爲以下方法切入點,橫切關注

「三明治」的代碼

methodA { 
    crosscut code 
    user code A 
    crosscut code 
} 

methodB { 
    crosscut code 
    user code B 
    crosscut code 
} 

是AOP易於橫切關注重疊到下面的用戶代碼?怎麼樣?

「意粉」 代碼

methodX { 
    user code x1 
    crosscut code 

    user code x2 
    crosscut code 
} 

methodY { 

    user code y1 
    crosscut code 

    user code y2 
    crosscut code 
} 

謝謝!

回答

4

Spring AOP的無助,因爲它只能理解執行()切入點。

AspectJ中包括了更多的切入點,包括withincode()構造,這聽起來像你想要什麼:

withincode(* YourClass.methodX(. .)) 

這可以讓你勸一個給定的方法exection內的所有連接點

AspectJ in Action有關更多信息,這是關於AspectJ和Spring AOP的一本很好的書。


編輯:

這裏是一些示例代碼:

package com.dummy.aspectj; 

import java.util.Arrays; 
import java.util.Collections; 

public class DummyClass{ 

    public static void main(final String[] args){ 
     System.out.println(Arrays.asList("One", Collections.singleton("Two"))); 
     System.out.println("Enough?"); 
    } 

} 

package com.dummy.aspectj; 

import java.util.Arrays; 

public aspect DummyAspect{ 

    pointcut callWithinMain() : 
     withincode(* com.dummy.aspectj.DummyClass.main(..)) // anything inside DummyClass.main 
     && call(* *.*(..));         // but only method calls 

    before() : callWithinMain() { 
     System.out.println("\n***************************************************"); 
     System.out.println("** Calling:\n**\t" 
      + thisJoinPointStaticPart.getSignature() 
      + "\n** with arguments:\n**\t " 
      + Arrays.deepToString(thisJoinPoint.getArgs())); 
     System.out.println("***************************************************\n"); 
    } 

} 

運行Eclipse中的DummyClass/AJDT生成的輸出:

*************************************************** 
** Calling: 
** Set java.util.Collections.singleton(Object) 
** with arguments: 
** [Two] 
*************************************************** 


*************************************************** 
** Calling: 
** List java.util.Arrays.asList(Object[]) 
** with arguments: 
** [[One, [Two]]] 
*************************************************** 


*************************************************** 
** Calling: 
** void java.io.PrintStream.println(Object) 
** with arguments: 
** [[One, [Two]]] 
*************************************************** 

[One, [Two]] 

*************************************************** 
** Calling: 
** void java.io.PrintStream.println(String) 
** with arguments: 
** [Enough?] 
*************************************************** 

Enough? 
+0

你有一個方便的例子,所以把它放在這裏?感謝啓發! – sof 2010-08-17 16:34:58

+0

看到我的更新後的一些示例代碼 – 2010-08-18 13:35:28

+0

哦!足以消化。正如我所說, – sof 2010-08-18 14:21:21

2

儘管某些AOP實現可能允許您這樣做,但這可能意味着需要將這些方法重構爲更多組合方法,因爲如果需要將關注點切入方法的中間位置,它們可能會做得太多。 這樣做會給你:

methodX 
{ 
    usercodemethod1(); 
    usercodemethod2(); 
} 

usercodemethod1 
{ 
    user code x1 
    crosscut code 
} 

usercodemethod2 
{ 
    user code x2 
    crosscut code 
} 
+0

我們做重構而言最佳實踐。 AOP重構是否是一個良好的實踐?如果不是這樣,我們會承認AOP容易出現相當嚴格的問題域,例如綠燈交易分界,但紅色記錄。 – sof 2010-08-17 16:27:00

+0

我不會說應該重構只是爲了迎合AOP,但正如@seanizer所提到的那樣,Spring對此沒有幫助,所以如果你要走這條路線,這可能是最好的選擇 - 任何代理(運行時)基於瀏覽器的AOP通常不會支持將代碼編入方法的中間 – saret 2010-08-17 16:35:01

+0

@saret:這不適用於基於代理的aop。當methodX調用usercodemethod1(假設它們在同一個類中)時,它不會調用代理,而是調用實際的類(您已經在代理中),所以建議不會有機會執行。因此,實現這一目標的唯一方法是讓整個工作流程從外部訪問(客戶端調用usercodemethod1,然後是usercodemethod2等),這將大大違反DRY原則。 – 2010-08-18 06:55:23