2016-07-14 4 views
0

현재 부모 클래스의 메소드 호출을 포착하는 pointcut이 있습니다.하위 클래스를 포착하지 않는 pointcut을 작성하려면 어떻게해야합니까?

는 내가 가지고있는 것은 내 상속 구조가 B입니다

@After("call (public void ParentInterface.method(..)) && target(instance)") 
public void intercept(A instance) { 
} 

ParentInterface입니다. pointcut이 method()에 대한 B의 호출을 가로채는 것을 원하지 않습니다. 이것이 가능한가?

편집 : 같은 for 루프있을 때 다음 때문에

@After("call (public void A.method(..)) && target(instance)") 

:

for(ParentInterface obj:list) { 
    obj.method(); 
} 

호출로 인해 차단되지 않을 것이다 내가이되고 싶지 않아 그것을 가로 채는 pointcut은 없다.

+1

pointcut에서 "if"문을 사용할 수 있습니다. call (public void A.method (..)) && target (instance) && if (! 인스턴스 instanceof B)). - https://eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-pcadvice.html – Lin

+0

@Lin을 참조하십시오. pointcut에서 if 문을 사용할 수 있다는 사실을 전혀 알지 못했고, 더 많은 것을 테스트 할 것입니다. 단 한가지는 내가 할 것이라고 생각하지 않는다! instanceof 그러면 각 하위 클래스에 하나씩 포함시켜야하기 때문에 if (instance.getClass() == A.class) 라인을 따라 뭔가를 시도 할 것이다. 감사! – jhwang

답변

0

AFAIK은, 불행하게도 당신은 포인트 컷과 함께 직접 할 수는 없지만 대신 조언에 반사를 사용할 수 있습니다

package de.scrum_master.app; 

public interface ParentInterface { 
    void myMethod(); 
} 
package de.scrum_master.app; 

public class A implements ParentInterface { 
    @Override 
    public void myMethod() { 
     System.out.println(" myMethod -> " + this + "\n"); 
    } 
} 
package de.scrum_master.app; 

public class B extends A { 
    public void doSomething() { 
     System.out.println(" doSomething -> " + this); 
     myMethod(); 
    } 

    public static void main(String[] args) { 
     new A().myMethod(); 
     new B().doSomething(); 

     ParentInterface[] objects = { new A(), new B(), new A(), new B() }; 
     for (ParentInterface object : objects) 
      object.myMethod(); 
    } 
} 
package de.scrum_master.aspect; 

import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.After; 
import org.aspectj.lang.annotation.Aspect; 

import de.scrum_master.app.A; 

@Aspect 
public class MyAspect { 
    @After("call(public void de.scrum_master.app.ParentInterface.myMethod(..)) && target(instance)") 
    public void intercept(A instance, JoinPoint thisJoinPoint) { 
     if (instance.getClass() != A.class) 
      return; 
     System.out.println(thisJoinPoint); 
    } 
} 

이제 어떻게 로그 출력 만 유의하시기 바랍니다 예를 들어 A의 인스 타 스먼트에서 aspect 출력을 표시하지만, B과 같은 서브 클래스에는 나타나지 않습니다.

call(void de.scrum_master.app.A.myMethod()) 
    myMethod -> [email protected] 

    doSomething -> [email protected] 
    myMethod -> [email protected] 

call(void de.scrum_master.app.ParentInterface.myMethod()) 
    myMethod -> [email protected] 

    myMethod -> [email protected] 

call(void de.scrum_master.app.ParentInterface.myMethod()) 
    myMethod -> [email protected] 

    myMethod -> [email protected] 
+0

pointcut에서 if 문을 사용하지 않는 이유는 무엇입니까? 다음과 같은 것 : call (public void A.method (..)) && target (instance) && if (! instance instanceof B)) ...? – Lin

+0

'A'는'B' 이외의 서브 클래스를 가질 수 있고 솔루션은 일반적인 것이 아니기 때문에. 물론 조건을 pointcut 내의'if()'조건에 넣을 수는 있지만'... && if (instance.getClass()! = A.class)' – kriegaex

+0

또한 주석에 스타일 문법 당신은 정적 일 필요가있는 여분의 메소드가 필요합니다. 이것은 네이티브 AspectJ 구문으로 만 작동한다고 제안하는 것입니다. 이것이 제가 처음에 제안하지 않은 이유입니다. 어노테이션 스타일은 pointcut 내에서'if()'조건을 사용하는 방법이 제한되어 있으므로, @AspectJ 스타일로만 작동하는 솔루션이 내 솔루션이다. – kriegaex