2011-12-09 83 views
0

首先我需要說我是Spring AOP中的新成員(當然,我是AOP中的新成員)。 在我的應用程序中,我有服務類是由方面建議,單位這一點是沒有問題的。方面被觸發,每一個作品。但是我需要從我的角度調用該服務方法,並且存在問題。我的方面是(邏輯)觸發每個調用和每個結束StackOwerflow錯誤。Spring AOP - 方面循環執行

可以防止該方面循環?

我有想法創建IAspectSandbox接口(或類)和方法調用從類將實現此接口不觸發方面。但我真的不知道該如何實現這個目標:)

我的類架構:

@Service 
public class MyService 
{ 
    public BarObject update(FooObject item) 
    { 
     BarObject barObject = new BarObject(); 
     // save FooObject to database and detect changes against old row 
     // information about fields, that was changed is in BarObject 
     return barObject; 
    } 
} 

-------------------------------------------------------------------------- 

@Aspect 
public class MyServicePointcut 
{ 
    @Pointcut("execution(* cz.package.service.MyService.update(..))") 
    public void myServiceItemChanged() {} 
} 

-------------------------------------------------------------------------- 

@Component 
@Aspect 
public class PraceZadaniChangeAspect 
{ 

    @AutoWire 
    private MyService myService; 


    @AfterReturning("cz.package.pointcuts.MyServicePointcut.myServiceItemChanged()", returning = "returnVal") 
    public void execute(BarObject returnVal) 
    { 
     // do something with BarObject ... mostly check changes 
      // ..... 
      // ..... 
      // at the end I need to save changes 
     myService.update(returnVal.getFooObject()); // after this call is this aspect triggered again. I know why, but I don't want to :) 
    } 
} 

回答

2

答案#1:調用勸方法只(around通知)

如果自動裝配你的服務回到你的方面,你仍然在調用Spring的代理機制,包括你已經應用到你的服務的AOP方面。

請參閱 「Around通知」 在Spring AOP章:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-ataspectj-around-advice

基本上,做這樣的事情:

@AfterReturning("...") 
public void execute(ProceedingJoinPoint p, BarObject returnVal) 
{ 
    // do something with BarObject 
    // ... 
    // call original method with original args 
    p.proceed(p.getArgs()); 
} 

我不是100%確定的代碼,但proceed()應該直接調用目標方法而不遞歸地調用AOP代理。

答案#2:調用多重目標對象的方法

如果你需要打電話給你的方面中從服務對象的多種方法,你會通過getTarget()需要訪問對象非代理:

@AfterReturning("...") 
public void execute(JoinPoint p, BarObject returnVal) 
{ 
    // do something with BarObject 
    // ... 
    // call various service methods without triggering this AOP proxy again 
    // by using getTarget() to get the unproxied object: 
    MyService myService = (MyService) p.getTarget(); 
    myService.update(...);    // does not trigger AOP interceptor 
    myService.otherMethod(...);   // neither does this 
    myService.thirdMethod(...);   // nor this 
} 
+0

我明白你的意思,但我正在考慮編寫切入點規則。以某種方式排除來自特定類(或實現特定接口的類)的調用。但我不確定這是否可能。 – Peter

+0

你可以使用'!'來執行切入點中的類..檢查參考[here](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html #aop-pointcuts-combining) –

+0

是的,我知道,但我需要排除調用該服務類方法的類。我需要從我的方面排除所有方法調用到服務類。我不確定在Spring AOP中這是否可能。 – Peter