2009-02-23 8 views
16

मैं कुछ वर्ग माईक्लास को सभी सेट इनवॉक्शंस पर प्रतिक्रिया करने में सक्षम होने के लिए सभी विधि आमंत्रणों को अवरुद्ध करना चाहता हूं।मैं मानक जावा सुविधाओं (कोई AspectJ आदि) के साथ एक विधि आमंत्रण कैसे रोकूं?

मैंने गतिशील प्रॉक्सी का उपयोग करने की कोशिश की, लेकिन जहां तक ​​मुझे पता है, यह केवल कुछ इंटरफेस को लागू करने वाले वर्गों के लिए काम करता है। लेकिन MyClass में ऐसा इंटरफ़ेस नहीं है।

क्या कोई अन्य तरीका है, एक रैपर वर्ग को लागू करने के अलावा, जो किसी सदस्य को सभी आमंत्रणों का प्रतिनिधित्व करता है, जो MyClass का उदाहरण है या AOP का उपयोग करने के बगल में है?

उत्तर

23

आप ध्यान दें के रूप में, आप JDK गतिशील प्रॉक्सी (कोई इंटरफेस) का उपयोग नहीं कर सकते, लेकिन Spring और CGLIB का उपयोग कर (जार वसंत के साथ शामिल है), तो आप निम्न कर सकते हैं:

public class Foo 
{ 
    public void setBar() 
    { 
     throw new UnsupportedOperationException("should not go here"); 
    } 

    public void redirected() 
    { 
     System.out.println("Yiha"); 
    } 
} 

Foo foo = new Foo(); 
ProxyFactory pf = new ProxyFactory(foo); 

pf.addAdvice(new MethodInterceptor() 
{ 
    public Object invoke(MethodInvocation mi) throws Throwable 
    { 
     if (mi.getMethod().getName().startsWith("set")) 
     { 
      Method redirect = mi.getThis().getClass().getMethod("redirected"); 
      redirect.invoke(mi.getThis()); 
     } 
     return null; 
    } 
}); 

Foo proxy = (Foo) pf.getProxy(); 
proxy.setBar(); // prints "Yiha" 
+0

धन्यवाद! मेरा दिन बचाया –

+0

किसी विधि को रोकते समय, क्या पास किए गए तर्कों को पढ़ना संभव है? – aryaxt

+0

हाँ कि संभव है ... के लिए (वस्तु आर्ग: mi.getArguments()) { \t \t \t \t sysout (arg.getClass() + "-" + आर्ग); \t \t \t} – Skabdus

13

आप वास्तव में कुछ बदसूरत करने के लिए तैयार हैं, पर एक नजर है:

http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/

मूल रूप से डिबगर इंटरफ़ेस आप एक डिबगर तरह संलग्न करने के लिए अनुमति देने के लिए चाहिए, और इसलिए कॉल अवरोधन। ध्यान रखें मुझे लगता है कि यह वास्तव में खराब विचार है, लेकिन आपने पूछा कि क्या यह संभव था।

+8

हैक मान –

+0

से सहमत है। काफी बदसूरत – Jus12

0

AspectJ में बहुत अधिक जादू नहीं है। आप अपना खुद का एजेंट लिख सकते हैं। http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html अच्छा प्रारंभिक बिंदु प्रतीत होता है।

+1

मुझे लगता है कि आप उत्पादन गुणवत्ता एजेंटों के लिए आवश्यक काम को कम से कम समझते हैं। –

+0

क्षमा करें, मेरा मतलब AspectJ से कोई क्रेडिट नहीं लेना था। यह एक अद्भुत बात है और मैं इसे बहुत सफलतापूर्वक उपयोग कर रहा हूं। मुझे केवल यह कहना था कि विचारों को रोकने के लिए एक साधारण एजेंट लिखना बहुत मुश्किल नहीं है। मुझे सही करने के लिए धन्यवाद। –

2

जावा विधि अवरोधन (यकीन नहीं किसी भी स्थिर भाषा करता है)

मैं थोड़े डिबगर इंटरफेस का उपयोग करने का निक के विचार पसंद, यह सिर्फ मतलब है के लिए किसी भी वास्तविक भाषा सुविधाएँ नहीं हैं।

मुझे लगता है कि आपको जिस छोटे उत्तर की आवश्यकता है वह है: जावा में एक विधि कॉल को अवरुद्ध करने का कोई तरीका नहीं है, वास्तव में प्रॉक्सी या रैपर का उपयोग करके कक्षा को प्रतिस्थापित किए बिना।

नोट: एओपी पुस्तकालयों ने इसे स्वचालित रूप से स्वचालित रूप से किया है।

1

कुछ जावा गुरु इस पर फहरा सकते हैं लेकिन मुझे आदिम प्रकारों और सेटर्स से पूरी तरह से बचने के साथ कुछ अच्छी सफलता मिली है। मेरी कक्षा इस तरह दिखती है:

class Employee extends SmartPojo { 
    public SmartString name; 
    public SmartInt age; 
} 

आप दो चीजें देखेंगे: 1. सबकुछ सार्वजनिक है। 2. कोई कन्स्ट्रक्टर नहीं।

जादू स्मार्टपोजो में होता है जो किसी भी क्षेत्र की खोज करता है जो "स्मार्ट" इंटरफ़ेस लागू करता है और इसे प्रारंभ करता है। चूंकि यह कोई आदिम (और कोई अंतिम श्रेणी नहीं है), इसलिए मैं अपने मॉडल में कहीं भी एक ही स्थान में सभी फ़ील्ड के लिए सेट() और get() विधियों जोड़ सकता हूं। तो अब कोई भीटर/गेटर कचरा नहीं है, यह अधिसूचना जोड़ने के लिए आश्चर्यजनक रूप से सरल है (एक ही स्थान पर), आदि

सच है, यह अब कोई POJO नहीं है और यह ज्यादातर तरीकों से बीन नहीं है लेकिन मुझे पता चला है कि ये पुराने विचार मुझे मदद से ज्यादा सीमित करते हैं। YMMV।

+0

यह मूल रूप से grails उनके डोमेन ऑब्जेक्ट्स के साथ करता है। हालांकि, क्योंकि वे इसे ग्रोवी के साथ कार्यान्वित कर सकते हैं, यह बहुत अच्छा है, और उन्हें "स्मार्ट" इंटरफ़ेस को लागू करने वाली प्रत्येक संपत्ति की आवश्यकता नहीं होगी। – Chii

+0

मुझे जावा केवल समाधान की आवश्यकता थी। मैंने ग्रोवी के साथ भी यह कोशिश की है, जबकि कोड बहुत अधिक कॉम्पैक्ट है, यह उतना अच्छा नहीं है। मैं ग्रोवी का एक बड़ा प्रशंसक हूं लेकिन मुझे लगता है कि 1.x अभी भी थोड़ा सा है ... "अधूरा"। –

+0

क्या आप 'स्मार्टपोजो' के लिए कोड साझा कर सकते हैं? –

0
  1. आपकी कक्षा इंटरफ़ेस को क्यों लागू नहीं कर सकती? आप बस कुछ इंटरफ़ेस निकाल सकते हैं जिसमें सभी विधियां शामिल हैं जिन्हें आप अवरुद्ध करना चाहते हैं और गतिशील प्रॉक्सी तंत्र का आसानी से उपयोग कर सकते हैं। इंटरफेस के साथ कोड करने के लिए यह कक्षाओं के लिए भी एक अच्छा प्रोग्रामिंग अभ्यास है।

  2. आप स्प्रिंग एओपी क्षमताओं (जो अंदर गतिशील प्रॉक्सी का उपयोग कर रहे हैं) के साथ स्प्रिंग फ्रेमवर्क का उपयोग कर सकते हैं।आपको कॉन्फ़िगरेशन फ़ाइल में स्प्रिंग बीन के रूप में अपनी कक्षा को परिभाषित करना होगा और आपकी कक्षा के क्लाइंट को या तो स्प्रिंग एप्लिकेशन संदर्भ से या एक निर्भरता के रूप में अपना उदाहरण प्राप्त करना होगा (उदाहरण के लिए setMyClass (MyClass mc) विधि को परिभाषित करके)। वहां से आप आसानी से ऐसे पहलू को परिभाषित करने जा सकते हैं जो इस वर्ग में सभी विधि कॉल को रोकता है।

+0

शायद वह एक कक्षा को डीबग करने की कोशिश कर रहा है जिसे उसने कुछ तृतीय पक्ष पुस्तकालय में नहीं लिखा था? –

2

मैं सिर्फ विकसित इस उद्देश्य के लिए एक छोटा ढांचा। आप इसे यहां देख सकते हैं: http://code.google.com/p/java-interceptor/ (चेक आउट करने के लिए svn का उपयोग करें)।

+1

क्या आप संक्षेप में समझा सकते हैं कि यह कैसे काम करता है/यह क्या करता है? – avalancha

0

जावा विधि invoketion के अवरोध के लिए एक AspectJ उपयोग करने के लिए अच्छा उपकरण है। जिसके माध्यम से mthod कॉल, निष्पादन इत्यादि को प्रभावी ढंग से रोक सकते हैं। मैं जावा विधि कॉल को रोकने के लिए एक ही उपकरण में हूं। हम किसी जावा विधि कॉल को इंटरसेप्ट करने के लिए पॉइंटकट्स ansd पहलुओं को लागू कर सकते हैं। केवल जानकारी के लिए this

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