2016-07-14 4 views
0

現在、私はメソッドの親クラスの呼び出しをキャッチするポイントカットを持っています。サブクラスを捕捉しないポイントカットを作成するにはどうすればよいですか?

私は何を持っていることである:私の継承構造は、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(); 
} 

コールが原因で傍受されることはない、私はそれをしたくない それを傍受するポイントカットはありません。

+1

pointcutに "if"文を使うことができます:call(public void A.method(..))&& target(instance)&& if(!)インスタンスinstanceofB))。 - https://eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-pcadvice.html – Lin

+0

@Linを参照してください。私がpointcutsでif文を持つことができなかったことに全く気付かず、もっとテストします。私はそうするつもりはないと思うのですが、instanceofというのは、各サブクラスごとに1つずつ含める必要があるからです。おそらく、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

関連する問題