2012-08-01 21 views
15

Parametrenin hangi konumda bulunduğundan bağımsız olarak, belirli bir açıklama ile açıklanmış bir parametreyi içeren yöntemlerle eşleştirmek için bir pointcut ifadesi tanımlamaya çalışıyorum. @Constraint ek açıklaması için.AspectJ pointcut expression parametresi, herhangi bir konumda parametre açıklamaları ile eşleşiyor

Eşleştirme yöntemleri:: Şimdiye kadar hiçbir şans ile aşağıdaki ifadeleri denedim

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) 

: Örneğin

@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 

birisi doğru çözüme işaret edebilir? mümkün mü?

+0

Bunun bir eski olduğunu biliyorum, ancak yine de yanıtlanmamış olarak listelenir. Uygun göründüğünde cevabımı kabul edip yanıtı verir misiniz lütfen? Teşekkürler. – kriegaex

cevap

12

Bir bağımsız değişkeni AspectJ'de args() aracılığıyla rastgele bir konuma bağlayamazsınız, çünkü bu durum belirsizliğe neden olabilir. Sadece aynı tipte iki veya daha fazla parametreniz olduğunu (veya bu durumda aynı açıklama türüyle açıklamalı) hayal edin. Bunlardan hangisi args() parametresine bağlı olmalıdır?

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

(yıldızın etrafında parantez lütfen unutmayın) tek başına bir ifadesi olarak mümkün iken Yani, args() birlikte mümkün değildir. Öyleyse, sadece yöntem yürütmesinin kendisini durdurmak istemezseniz, aynı zamanda verilen ek açıklama ile ilk ya da tüm parametreleri bulursanız, diğer makalede gösterdiğim şeyi yapmanız gerekir. Bir tür yine mi silinecek cevabı için sırayla kendimi tekrar ama öyle olsun am: Gördüğünüz gibi

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++; 
     } 
    } 
} 

, bir bir ek açıklamaları almak için biraz daha zordur parametresini yalnızca bildirilen türden değil, temelde önceki yazıdakiyle aynı şekilde çalışır, yani argüman listesi üzerinde yineleme yaparak.

1

Sanırım execution(public * *.*(.., @com.example.Constraint *, ..), modulo bazı sözdizimi.

+0

Hayır, yukarıda gösterilen tüm durumlar için çalışmaz. – kriegaex