2011-08-24 24 views
12

मैं एक पहलू पॉइंटकट कैसे लिख सकता हूं जो विधि निष्पादन पर लागू होता है जो एनोटेशन विधि के साथ एक इंटरफ़ेस विधि को ओवरराइड करता है? उदाहरण के लिए:@AspectJ पॉइंटकट जो विधियों के लिए एक इंटरफ़ेस विधि को ओवरराइड करते हैं

interface A { 
    @MyAnnotation void method(); 
} 
class B implements A { 
    void method(); 
} 

pointcut execution(@MyAnnotation * *.*(..)) केवल मेल खाते हैं, तो B.method() एनोटेशन ही किया जाता है है। क्या इसे करने का और कोई तरीका है?

उत्तर

10

जैसा कि निकोलस ने बताया, यह AspectJ में संभव नहीं है। यहां इसका कारण यह संभव नहीं है की अधिक सबूत (http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html अनुभाग व्याख्या विरासत और pointcut मिलान से लिया गया) है:

जावा 5 विनिर्देश के अनुसार, गैर प्रकार एनोटेशन नहीं ली गई है, और प्रकार पर भी टिप्पणियां ही कर रहे हैं विरासत में मिला अगर उनके पास @ अंतर्निहित मेटा-एनोटेशन है। C2.aMethod (जो आपके उदाहरण में b.method() होगा) मिलान नहीं किया गया है क्योंकि संशोधक बिंदु (दृश्यता संशोधक, एनोटेशन, और फेंकता खंड) के लिए बिंदु मिलान में शामिल होना शामिल बिंदु के विषय पर आधारित है (वास्तव में विधि कहा जा रहा है)।

इसी मुद्दे से पीड़ित होने के बाद, मैंने एक छोटी सी विधि/लाइब्रेरी लिखी है जो आपको इस तरह के तरीकों के लिए पॉइंटकट लिखने की अनुमति देगी।यहाँ यह है कि आपके उदाहरण के लिए काम करेगा है:

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

या

myAnnotationIsExecuted(): execution(public * A+.*(..)) && 
      if(implementsAnnotation("@MyAnnotation()", thisJoinPoint)); 

विधि implementsAnnotation(String,JoinPoint) पुस्तकालय से आ रही है; एक मूल विधि जो जांचती है कि लागू विधियों में निर्दिष्ट एनोटेशन है या नहीं।

विधि/पुस्तकालय के बारे में अधिक जानकारी here.

3

अद्यतन

ऐसा लगता है कि यह वसंत में (मूल जवाब देखें) मैं कहूँगा कि आप को लागू करने की कक्षाओं पर प्रत्येक विधि के लिए एनोटेशन जोड़ने की जरूरत नहीं किया जा सकता है के बाद से। ऐसा करने का एक स्पष्ट तरीका है, लेकिन मुझे लगता है कि यदि आप एक अधिक स्वचालित तरीके की तलाश में हैं तो आपको खुद को लिखना होगा।

मैं कुछ प्रकार के घर से उगाए जाने वाले पोस्ट प्रोसेसर की कल्पना कर सकता हूं जो एक विशिष्ट एनोटेशन की तलाश करेगा, @ApplyThisAnnotationToAllWhoInheritMe कहें। एक बार यह एनोटेशन मिलने के बाद, यह सदस्यों को विरासत के लिए स्रोत कोड स्कैन करेगा और अनुरोधित एनोटेशन जोड़ें जहां संकलन होने से पहले आवश्यक हो।

भले ही, यदि आप ऐसा करने के लिए स्प्रिंग एओपी का उपयोग कर रहे हैं, तो ऐसा लगता है कि इसे कार्यान्वयनकर्ता विधि पर होना आवश्यक है। यदि आप जिन कक्षाओं की उम्मीद कर रहे हैं, वे आपकी नियंत्रण से बाहर निकलने में मदद करेंगे, तो आपको अपना खुद का वसंत एओपी उपकरण लिखना पड़ सकता है।

मूल उत्तर

Spring 3.0 Documentation से

:

AspectJ जावा के नियम यह है कि इंटरफेस पर भी टिप्पणियां नहीं ली गई है इस प्रकार है।

मैं अनुभाग 7.8.2 Other Spring aspects for AspectJ में इस बिट, जो 7.8 Using AspectJ with Spring applications का एक हिस्सा है, जो मुझे लगता है कि यह एक वैश्विक नियम है बनाता है पाया।

+0

धन्यवाद; जो बताता है कि मेरा पॉइंटकट क्यों काम नहीं करता है। हालांकि, मैं एक काम कर रहा हूं जो काम करता है। :-) –

+0

@hstoerr: आपके प्रश्न को संपादित करने के बाद, मैंने अपना जवाब संपादित किया। अगर मुझे अभी भी अस्वीकार्य है तो मुझे बताएं। –

+1

वसंत प्रलेखन वास्तव में यह नहीं कहता कि मुझे जो कुछ चाहिए, उससे मेल खाना असंभव है - बस इतना आसान तरीका मैंने कोशिश नहीं की है। एस्पेक्ट में कुछ अजीब बात हो सकती है जिसे मैं नहीं सोच सकता। तो मैं अभी भी उम्मीद कर रहा हूँ। :-) –

2
//introducing empty marker interface 
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker; 

public pointcut p1() : execution(* TrackedParentMarker+.*(..)); 

इसके अलावा, आप -XhasMember संकलक झंडा सक्षम होना चाहिए।

+0

दुर्भाग्यवश यह काफी नहीं करता है। यह उन सभी वर्गों की प्रत्येक विधि पर लागू होता है जो एक इंटरफेस को कार्यान्वित करते हैं जिसमें कम से कम एक विधि है जो एनोटेशन करती है। लेकिन इसे केवल एक विधि पर लागू होना चाहिए जो उस मार्कर के साथ इंटरफेस विधि लागू करता है। या कम से कम विधियों के लिए जिनके पास समान इंटरफ़ेस विधि के साथ समान नाम है, यदि AspectJ में यह कहना संभव है। –

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

  • कोई संबंधित समस्या नहीं^_^