2016-07-14 33 views
0

目前我有一個切入點可以捕獲父類的方法調用。如何編寫不捕獲子類的切入點?

我所擁有的是:

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

凡我繼承結構是一個ParentInterface。 我不希望切入點截獲B對method()的調用的任何實例。這可能嗎?

編輯: 我不希望它是:

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

因爲當有一個for循環,例如:

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

呼叫不會因爲攔截沒有切入它的切入點。

+1

您可以在切入點中使用「if」語句 - 如下所示:call(public void A.method(..))&& target(instance)&& if(! instanceof B))。請參閱 - https://eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-pcadvice.html – Lin

+0

@林完全沒有注意到,如果在切入點中的語句可以測試更多。唯一的事情是我不認爲我會這麼做!因爲那麼我將不得不爲每個子類包含一個,我可能會嘗試沿着if(instance.getClass()== A.class)的行。謝謝! – jhwang

回答

0

據我所知,不幸的是你不能直接跟一個切入點做到這一點,但你可以在你的建議使用反射來代替:

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,但不在子類如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

爲什麼不在切入點中使用if語句?例如:call(public void A.method(..))&& target(instance)&& if(!instance instanceof B))...? – Lin

+0

由於'A'可能具有「B」以外的子類,且解決方案不是通用的。當然,你可以在切入點中將條件放入一個'if()'條件,但是仍然應該是:'... && if(instance.getClass()!= A.class)' – kriegaex

+0

此外,在註釋類型的語法需要一個額外的方法,它需要是靜態的,你所建議的只適用於本地的AspectJ語法。這就是爲什麼我沒有首先提出這個建議。註釋樣式在切入點中使用'if()'條件的手段有限,我的解決方案是唯一能夠在@AspectJ樣式中工作的方法。 – kriegaex

相關問題