2012-08-01 18 views
15

पर AspectJ पॉइंटकट अभिव्यक्ति मिलान पैरामीटर एनोटेशन मैं पैरामीटर में किस स्थिति की परवाह किए बिना, एक विशिष्ट एनोटेशन के साथ एनोटेटेड पैरामीटर वाले विधियों से मिलान करने के लिए पॉइंटकट अभिव्यक्ति को परिभाषित करने का प्रयास कर रहा हूं। मेरे मामले में मैं देख रहा हूं @Constraint एनोटेशन के लिए।किसी भी स्थिति

मिलान तरीके::

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

मुझे पता है कि यह एक पुराना है, लेकिन अभी भी अनुत्तरित के रूप में सूचीबद्ध है। यदि आप उपयुक्त लगते हैं तो क्या आप कृपया मेरे उत्तर को स्वीकार करेंगे और ऊपर उठाएंगे? धन्यवाद। – kriegaex

उत्तर

12

आप AspectJ में args() के माध्यम से मनमानी स्थिति पर एक तर्क को बाध्य नहीं कर सकते क्योंकि इससे अस्पष्टता हो सकती है। बस कल्पना करें कि आपके पास एक ही प्रकार के दो या अधिक पैरामीटर हैं (या इस मामले में एक ही एनोटेशन प्रकार द्वारा एनोटेटेड)। उनमें से कौन सा नाम 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++; 
     } 
    } 
} 

आप देख सकते हैं, यह थोड़ा जटिल काम है एक की एनोटेशन प्राप्त करने के लिए केवल घोषित प्रकार की तुलना में दिया गया पैरामीटर, लेकिन मूल रूप से यह मेरी पिछली पोस्ट में समान रूप से काम करता है, यानी तर्कों की सूची में पुनरावृत्ति करके।

1

मुझे लगता है कि आप execution(public * *.*(.., @com.example.Constraint *, ..) चाहते हैं, कुछ वाक्यविन्यास modulo।

+0

नहीं, यह ऊपर दिखाए गए सभी मामलों के लिए काम नहीं करता है। – kriegaex

संबंधित मुद्दे