मैं एक कस्टम एनोटेशन के साथ एनोटेटेड विधि के आसपास एक पॉइंटकट को परिभाषित करने की कोशिश कर रहा हूं। एनोटेशन में एक पैरामीटर है जिसे मैं पॉइंटकट परिभाषा में एक चेक शामिल करना चाहूंगा।
यह एनोटेशन है:
public @interface MyAnno {
String[] types;
}
एनोटेशन कैसे लागू किया जा सकता है इसका एक उदाहरण:
public class MyClass {
@MyAnno(types={"type1", "type2"})
public void doSomething() {
// ...
}
@MyAnno(types={"type3"})
public void doSomethingElse() {
// ...
}
}
अब मैं दो पॉइंटकट परिभाषाएं चाहता हूं जो एनोटेशन की सामग्री के आधार पर उन दो विधियों का चयन करें।
एनोटेशन पर ही पॉइंटकट बनाना अपेक्षाकृत आसान है:
@Pointcut("@annotation(myAnno)")
public void pointcutAnno(MyAnno myAnno) {
}
@Pointcut("execution(* *(..)) && pointcutAnno(myAnno)")
public void pointcut(MyAnno myAnno) {
}
यह @MyAnno की हर घटना से मेल खाएगा। लेकिन मैं दो पॉइंटकट को कैसे परिभाषित कर सकता हूं, एक मिलान @MyAnno
के साथ types
जिसमें "type1"
और दूसरा मिलान @MyAnno
types
के साथ "type3"
2 जवाब
वर्तमान में AspectJ अनुमत प्रकार के एनोटेशन मान के सबसेट के लिए एनोटेशन मान मिलान का समर्थन करता है। दुर्भाग्य से आप जिस सरणी प्रकार का उपयोग कर रहे हैं वह समर्थित नहीं है (वर्ग भी समर्थित नहीं है)। यह सुविधा 1.6.0 AspectJ README (https://eclipse में प्रलेखित है। org/aspectj/doc/released/README-160.html)। 'एनोटेशन वैल्यू मैचिंग' पर एक सेक्शन है। जैसा कि वहां वर्णित है, मूल मामलों के लिए वाक्यविन्यास वास्तव में काफी सहज है:
enum TraceLevel { NONE, LEVEL1, LEVEL2, LEVEL3 }
@interface Trace {
TraceLevel value() default TraceLevel.LEVEL1;
}
aspect X {
// Advise all methods marked @Trace except those with a tracelevel of none
before(): execution(@Trace !@Trace(TraceLevel.NONE) * *(..)) {
System.err.println("tracing "+thisJoinPoint);
}
}
तो बस उस मूल्य को शामिल करें जिसका आप एनोटेशन में मिलान करना चाहते हैं। दुर्भाग्य से सरणी मामला अधिक जटिल है और इसलिए अभी तक लागू नहीं किया गया है। आपको यह निर्दिष्ट करने की अनुमति देने के लिए थोड़ा और सिंटैक्स की आवश्यकता है कि क्या आपके पॉइंटकट का अर्थ है 'कम से कम यह सरणी मान में' या 'बिल्कुल यह और केवल यह सरणी मान में'। संभवतः वह ..
संकेतन का पुन: उपयोग करेगा, ऐसा कुछ हो सकता है:
execution(@MyAnno(types={"type1"}) * *(..)) { // exactly and only 'type1'
execution(@MyAnno(types={"type1",..}) * *(..)) { // at least 'type1'
भाषा समर्थन के बिना मुझे डर है कि आपको अपने कोड में एनोटेशन के माध्यम से प्रोग्रामेटिक रूप से खोदना होगा ताकि यह जांच सके कि यह आपकी बाधा से मेल खाता है या नहीं।
आप इसे सशर्त पॉइंटकट के साथ कर सकते हैं लेकिन उनमें एनोटेशन विशेषता पर रनटाइम टेस्ट शामिल होगा।
मूल पहलू सिंटैक्स:
pointcut p(MyAnno myAnno): execution(* *(..))
&& @annotation(myAnno)
&& if(Arrays.stream(myAnno.types()).anyMatch("type1"::equals));
एनोटेशन आधारित पहलू सिंटैक्स:
@Pointcut("execution(* *(..)) && @annotation(myAnno) && if()")
public boolean pointcut(MyAnno myAnno) {
return !Arrays.stream(myAnno.types()).anyMatch("type1"::equals);
}
दोनों उदाहरणों के लिए java.util.Arrays
आयात करना न भूलें।
वर्तमान में, AspectJ संस्करण 1.8.13 के अनुसार, आप सरणी टाइप की गई एनोटेशन विशेषताओं पर पॉइंटकट अभिव्यक्तियों को स्थिर रूप से प्रतिबंधित नहीं कर सकते क्योंकि आप गैर-सरणी टाइप की गई विशेषताओं के साथ सक्षम होंगे, इसलिए इस समाधान में इसके बजाय एक रनटाइम परीक्षण शामिल होगा।
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।