2011-12-09 4 views
0

첫 번째로 나는 스프링 AOP에서 새로 온다고 말할 필요가있다. (글쎄, 나는 AOP에서 처음이다.) 내 응용 프로그램에서 나는 aspect에 의해 권고되는 서비스 클래스를 가지고 있으며,이 지점은 괜찮습니다. 애스 팩트가 트리거되고 모든 것이 작동합니다. 하지만 그 서비스 방법을 내 측면에서 호출해야하고 문제가 있습니다. My Aspect는 StackOverflow 오류가 발생할 때마다 각 호출 및 모든 끝에서 트리거됩니다 (논리적).스프링 AOP - 애스펙트 루프 실행

어 스펙트 루핑을 방지 할 수 있습니까?

이 인터페이스를 구현하는 클래스에서 IAspectSandbox 인터페이스 (또는 클래스) 및 메서드 호출을 작성하여 aspect를 트리거하지 않아도됩니다. 하지만 난 정말이 목표를 :) 달성하는 방법을 모르는

내 클래스 스키마

@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 : 만

당신이 autowire하기 경우 (조언 주위) 방법을 자문 호출 귀하의 서비스를 귀하의 측면으로 되돌려 놓고, 귀하는 귀하의 서비스에 적용한 AOP 측면을 포함하여 여전히 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()를 통해 unproxied 개체에 액세스해야합니다 귀하의 측면에서 해당 서비스 개체에서 여러 메서드를 호출해야하는 경우 :

@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

관련 문제