2010-05-04 10 views
16

मैं एक विधि मिलान एक pointcut साथ एक पहलू को बनाने के लिए अगर जरूरत है:Pointcut मिलान तरीकों

  • सार्वजनिक है
  • इसकी वर्ग @Controller (अंत में नहीं है) के साथ टिप्पणी की जाती है
  • इसके पैरामीटर में से एक (कई हो सकता है) @MyParamAnnotation के साथ एनोटेट किया गया है।

मुझे लगता है कि पहली दो स्थितियां आसान हैं, लेकिन मुझे नहीं पता कि वसंत के साथ तीसरे को पूरा करना संभव है या नहीं। यदि ऐसा नहीं है, हो सकता है मैं इस पर बदल सकते हैं:

  • इसके मापदंडों का एक प्रकार com.me.MyType का एक उदाहरण है (या कुछ इंटरफ़ेस लागू करता है)

क्या आपको लगता है यह संभव है इस लक्ष्य को हासिल करें? और प्रदर्शन अच्छा होगा?

धन्यवाद

संपादित: एक मिलान विधि का एक उदाहरण है। जैसा कि आप देख सकते हैं, MyMethod को एनोटेट नहीं किया गया है (लेकिन यह हो सकता है)।

@Controller 
public class MyClass { 
    public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) { 
     ... 
    } 
} 

संपादित: समाधान मैं अंत में इस्तेमाल किया, @Espen उत्तरों के आधार पर। जैसा कि आप देख सकते हैं, मैंने अपनी स्थितियों को थोड़ा बदल दिया: कक्षा को वास्तव में @ नियंत्रक होने की आवश्यकता नहीं है।

@Around("execution(public * * (.., @SessionInject (*), ..))") 
public void methodAround(JoinPoint joinPoint) throws Exception { 
    ... 
} 

उत्तर

19

यह एक दिलचस्प समस्या थी, इसलिए मैंने मामले को हल करने के लिए थोड़ा नमूना आवेदन बनाया! (और यह Sinuhe की राय के साथ बाद में सुधार हुआ है।)

मैं एक DemoController वर्ग कि पहलू के लिए एक उदाहरण के रूप में कार्य करना चाहिए बनाया है:

@Controller 
public class DemoController { 

    public void soSomething(String s, @MyParamAnnotation Double d, Integer i) { 
    } 

    public void doSomething(String s, long l, @MyParamAnnotation int i) { 
    } 

    public void doSomething(@MyParamAnnotation String s) { 
    } 

    public void doSomething(long l) { 
    } 
} 

पहलू यह है कि एक के पहले तीन तरीकों पर बिंदु में शामिल होने के जोड़ देगा , लेकिन पिछले विधि जहां पैरामीटर @MyParamAnnotation साथ एनोटेट नहीं है नहीं:

@Aspect 
public class ParameterAspect { 

    @Pointcut("within(@org.springframework.stereotype.Controller *)") 
    public void beanAnnotatedWithAtController() { 
    } 

    @Pointcut("execution(public * *(.., @aspects.MyParamAnnotation (*), ..))") 
    public void methodWithAnnotationOnAtLeastOneParameter() { 
    } 

    @Before("beanAnnotatedWithAtController() " 
      + "&& methodWithAnnotationOnAtLeastOneParameter()") 
    public void beforeMethod() {  
     System.out.println("At least one of the parameters are " 
        + "annotated with @MyParamAnnotation"); 
    } 
} 

पहले pointcut @Controller के साथ चिह्नित कक्षाओं के अंदर सभी तरीकों पर एक joinpoint पैदा करेगा।

दूसरा pointcut एक joinpoint जब निम्न शर्तों को पूरा जोड़ देगा:

  • सार्वजनिक विधि
  • पहले * हर वापसी प्रकार का वाइल्डकार्ड है।
  • दूसरा * सभी वर्गों में सभी विधियों के लिए एक वाइल्डकार्ड है।
  • (.., एनोटेटेड पैरामीटर से पहले किसी भी प्रकार के कई मानकों तक शून्य से मेल खाता है।
  • @aspects.MyParamAnnotation (*), दिए गए एनोटेशन के साथ एनोटेटेड पैरामीटर से मेल खाता है।
  • ..) एनोटेटेड पैरामीटर के बाद किसी भी प्रकार के कई मानकों तक शून्य से मेल खाता है।

अंत में, @Before सलाह सभी विधियों को सलाह देती है जहां दोनों बिंदुओं में सभी स्थितियां संतुष्ट हैं।

पॉइंटकट आस्पेक्टजे और स्प्रिंग एओपी दोनों के साथ काम करता है!

जब प्रदर्शन की बात आती है। ओवरहेड छोटा है, खासकर एस्पेक्टजे के साथ जो संकलन-समय या लोड-टाइम पर बुनाई करता है।

+0

यह अच्छा लग रहा है, लेकिन यह वही नहीं है जो मैं ढूंढ रहा हूं। मैंने अधिक सटीक होने के लिए अपना प्रश्न संपादित किया। धन्यवाद। – sinuhepop

+1

मुझे इसे सरल बनाने के लिए एक विधि मिली है। मैंने अपना प्रश्न संपादित किया, लेकिन आप सभी क्रेडिट! धन्यवाद। – sinuhepop

+0

अच्छा संपादन! आपको इस तरह के प्रश्नों को देखने में खुशी हुई;) – sinuhepop

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