AOSD:應用AOP實現業務邏輯中, 我提出關注的接口;
其原文在javaeye上的討論狼平方也提出可以用event,或者intercepter。
當然不同的方式可以解決不同的問題。這里要討論一下AspectJ和Event以及intercepter的不同。

1. 先來看看event的方式:需要兩個對象Event和EventHandler(EventListener),event和eventHandler,屬于數據契約。換句話說,犧牲了編譯檢查的好處,當然可以應對變化時有一定的好處。一旦需求變化,代碼上的變動需要的工作量不少,更為嚴重的是,如狼平方所說的侵入性太強。
2  接著看interceptor的AOP,相對于Event方式,雖然都是基于數據契約,都給自己做轉型,但是代碼量少了(因為代碼生成),重要的是沒有event那樣的侵入性。
3. 狼平方做了改進,利用AOP來做brocastEvent的工作。需要做的工作還是很多,甚至我以為這個工作還不如直接用Interceptor來得直接。

如我在小議領域模型(Domain Model) 所說的Domain Service處理兩個邏輯:業務規則和流程邏輯,而AOSD:應用AOP實現業務邏輯要試圖解決的問題是流程上邏輯,而以上無論是那種方式,都無法解決一個問題:流程信息。
假定現有兩個流程如下:

public   class  DomainService  {
    
public   void  bizProcessA() {
        
        SomeObject instance 
=  doSomeAction();
        
    }


    
public   void  bizProcessB() {
        
        SomeObject instance 
=  doSomeAction();
        
    }

    
public  SomeObject doSomeAction() {
        
    }

}

這里我們關注的目標方法是doSomeAction(),在doSomeAction中我們希望做些額外的工作,
以狼平方的例子,比如:financialService.createRequestOfMoney(...);
那么無論是用event:

public  SomeObject doSomeAction() {
 
 brocastEvent(
new  Event());
}

還是interceptor:

public   class  SomeInterceptor  implements  MethodInterceptor   {
    
public  Object invoke(MethodInvocation invoke)  {
          obj 
=  invoke.proceed(); //  執行被攔截的方法完成業務操作       
       
 .
         financialService.createRequestOfMoney(.);
    }

}

我們注意到,這樣做的結果是在bizProcessA()和bizProcessB()的不同業務流程都將導致執行
financialService.createRequestOfMoney
不過我們的流程邏輯要求是:
在bizProcessA()的流程下,執行financialService.createRequestOfMoney
而在bizProcessB的流程下,不執行financialService.createRequestOfMoney。

很明顯無論是之上event,還是interceptor的AOP都無法解決這個問題。

面對這樣的需求,就需要改進或者重構:
1. 最簡單也最直接改doSomeAction(...)為doSomeAction(...boolean flag)。很明顯這樣的做法很不理想
2. 來點OO的, 將doSomeAction(...)分出去,作為一個接口,采用多態解決。不過依然需要解決動態加載問題,處理起來又需要費點手段。

真的只有這兩個手段了嗎?不!還有,那就是AspectJ
AspectJ提供了如下
within
withincode
withincode
cflow
cflowbelow

幾個內置的pointcut,將可以做到我們要的效果,代碼如下:

public  aspect ServiceAspect {
 pointcut bp(): cflow(call(
void  DomainService.bizProcessA(..)));
 pointcut action(): call(doSomeAction());

 SomeObject around() : bp() 
&&  action()  &&  args() {
  SomeObject instance 
=  proceed();
  financialService.createRequestOfMoney(.);
  
return  instance;
 }

}

很顯然,AspectJ提供了AOSD所需要的軍火。

BTW:本文不針對狼平方同學,只是借由其兩篇blog討論開來,解釋了AspectJ優點,以及為什么AspectJ是實現AOSD的最佳也是唯一軍火。
事實上很多時候,解決問題的方法有很多,本文旨在闡明AOSD為我們提供了另一條思路。歡迎討論和拍磚!

另補上我在javaeye討論貼的完整例子代碼,下載