2012-08-01 8 views
15

パラメータの位置に関係なく、特定の注釈で注釈が付けられたパラメータを含むメソッドと一致するようにポイントカット式を定義しようとしています。 @Constraint注釈の場合たとえば:AspectJのポイントカット式は、どの位置でもパラメータの注釈と一致します

マッチング方法:

public void method1(@Constraint Car car) 

public void method2(String id, @Constraint Plane plane) 

public void method3(Wheel wheel, @Constraint List<Train> trains, @Constraint Plane plane) 

public void method4(Motor motor, @Constraint Set<Train> trains, Bicycle bike, Wheel wheel) 

public void method5(Wing wing, Motorcycle moto, @Constraint Truck truck, Bicycle bike, Wheel wheel) 

は、これまでのところ、私は運では、次の式を試してみた:

@Before("execution(public * *.*(..)) and @args(com.example.Constraint)") // there can be only one parameter 
@Before("execution(public * *.*(..)) and @args(..,com.example.Constraint)") // parameter must be in last position 
@Before("execution(public * *.*(..)) and @args(com.example.Constraint,..)") // parameter must be in first position 
@Before("execution(public * *.*(..)) and (@args(com.example.Constraint,..) or @args(..,com.example.Constraint))") // parameter must be in first or last position, nothing in between 
@Before("execution(public * *.*(..)) and @args(..,com.example.Constraint,..)") // Invalid 

を誰かが適切なソリューションに私を指すことができますか?それは可能ですか?

+0

私はこれが古いと知っていますが、未回答のままです。適切と思われる場合は、私の答えを受け入れてupvoteしますか?ありがとう。 – kriegaex

答えて

12

AspectJのargs()を介して任意の位置に引数をバインドすることはできません。これはあいまいさを招く可能性があるためです。同じタイプの2つ以上のパラメータがある(または、この場合は同じアノテーションタイプでアノテーションされている)と考えてください。これらのうちどれを指定したargs()パラメータにバインドする必要がありますか?だから、

execution(public * *(.., @Deprecated (*), ..)) 

は、スタンドアローン式として可能であるが(星の周りの括弧に注意してください)、それはargs()との組み合わせでは不可能です。したがって、メソッドの実行そのものを傍受したいだけでなく、指定された注釈で最初またはすべてのパラメータを見つけたら、他の記事で示したことを実行する必要があります。私は、ちょっと自分自身を繰り返していますが、それは答えが再び削除されないためにも:あなたが見ることができるように

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

@Retention(RetentionPolicy.RUNTIME) 
public @interface Constraint {} 
import java.util.ArrayList; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 

public class Application { 
    public void method1(@Constraint int i) {} 
    public void method2(String id, @Constraint float f) {} 
    public void method3(int i, @Constraint List<String> strings, @Constraint String s) {} 
    public void method4(int i, @Constraint Set<Integer> numbers, float f, boolean b) {} 
    public void method5(boolean b, String s, @Constraint String s2, float f, int i) {} 
    public void notIntercepted(boolean b, String s, String s2, float f, int i) {} 

    public static void main(String[] args) { 
     List<String> strings = new ArrayList<String>(); 
     strings.add("foo"); 
     strings.add("bar"); 
     Set<Integer> numbers = new HashSet<Integer>(); 
     numbers.add(11); 
     numbers.add(22); 
     numbers.add(33); 

     Application app = new Application(); 
     app.method1(1); 
     app.method2("foo", 1f); 
     app.method3(1, strings, "foo"); 
     app.method4(1, numbers, 1f, true); 
     app.method5(false, "foo", "bar", 1f, 1); 
     app.notIntercepted(false, "foo", "bar", 1f, 1); 
    } 
} 
import java.lang.annotation.Annotation; 

import org.aspectj.lang.SoftException; 
import org.aspectj.lang.reflect.MethodSignature; 

public aspect ArgCatcherAspect { 
    before() : execution(public * *(.., @Constraint (*), ..)) { 
     System.out.println(thisJoinPointStaticPart); 
     MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature(); 
     String methodName = signature.getMethod().getName(); 
     Class<?>[] parameterTypes = signature.getMethod().getParameterTypes(); 
     Annotation[][] annotations; 
     try { 
      annotations = thisJoinPoint.getTarget().getClass(). 
       getMethod(methodName, parameterTypes).getParameterAnnotations(); 
     } catch (Exception e) { 
      throw new SoftException(e); 
     } 
     int i = 0; 
     for (Object arg : thisJoinPoint.getArgs()) { 
      for (Annotation annotation : annotations[i]) { 
       if (annotation.annotationType() == Constraint.class) 
        System.out.println(" " + annotation + " -> " + arg); 
      } 
      i++; 
     } 
    } 
} 

、Aの注釈を取得するには少しトリッキーです与えられたパラメータは宣言された型だけではありませんが、基本的には私の前のポストと同じように動作します。つまり引数のリストを繰り返し処理します。

1

私はあなたがexecution(public * *.*(.., @com.example.Constraint *, ..)、モジュロいくつかの構文をしたいと思います。

+0

いいえ、これは上記のすべてのケースで機能しません。 – kriegaex

関連する問題