2010-04-11 41 views
9

मैं javassist ProxyFactory के साथ प्रॉक्सी बना रहा हूं। एक प्रॉक्सी बनाते समय सभी ठीक काम करते हैं।जावासिस्ट: प्रॉक्सी की प्रॉक्सी कैसे बनाएं?

हालांकि, जब मैं प्रॉक्सी तंत्र के लिए एक प्रॉक्सी वस्तु गुजरती हैं, इसके साथ

javassist.bytecode.DuplicateMemberException विफल रहता है: नकल विधि: com.mypackage.Bean में setHandler _ $$ _ javassist_0 _ $$ _ javassist_1

मैं इस के साथ प्रॉक्सी बना रहा हूं:

public Object createProxiedInstance(Object originalInstance) throws Exception { 
    Class<?> originalClass = instance.getClass(); 
    ProxyFactory factory = new ProxyFactory(); 

    factory.setSuperclass(originalClass); 

    factory.setHandler(new MethodHandler() {..}); 
    Class<T> proxyClass = factory.createClass(); 

    return proxyClass.newInstance(); 
} 

तो, मैं कैसे की प्रॉक्सी प्रॉक्सी बना सकता हूँ?

अद्यतन: वास्तविक समस्याओं कि प्रत्येक प्रॉक्सी ProxyObject जो setHandler(..) पद्धति निर्धारित करता है को लागू करता है। तो दूसरी प्रॉक्सी उपclass में इसे ओवरराइड करने के बजाय विधि को फिर से परिभाषित करने की कोशिश कर रही है।

+0

बीटीडब्ल्यू, यह जावासवादी के बारे में पहला सवाल प्रतीत होता है। मैं आश्चर्यचकित हूँ। – Bozho

उत्तर

4

समस्या थी (वास्तव में, यह CGLIB के साथ समान है - मैंने इसे कॉमन्स-प्रॉक्सी का उपयोग करने की कोशिश की) कि मुझे प्रॉक्सी क्लास का प्रॉक्सी क्लास बनाने की कोशिश नहीं करनी चाहिए। दूसरी प्रॉक्सी फिर से मूल वर्ग का होना चाहिए। तो निम्नलिखित पंक्ति जोड़ना समस्या का समाधान:

if (instance instanceof ProxyObject) { 
    originalClass = originalClass.getSuperclass(); 
} 

और एक सलाह - अगर आप इंटरसेप्टर के कुछ प्रकार (कॉमन्स-प्रॉक्सी में परिभाषित लोगों की तरह), यह बजाय कई प्रॉक्सी का उपयोग करने का उपयोग कर सकते हैं करते हैं।

1

एक नहीं बल्कि देर से जवाब इसकी लेकिन आप अभी भी यह जानने में रुचि हो सकती:

Javassist प्रॉक्सी बल्कि भोलेपन से लागू किया जाता है। अपने उपरोक्त कोड में, Javassist हमेशा निम्न विधियों में से एक प्रॉक्सी वर्ग पैदा करेगा:

  1. आधार वर्ग के किसी भी overridable विधि के लिए एक विधि
  2. को दो तरीकों (क) एक प्रॉक्सी हैंडलर (getHandler) हो जाते हैं और (ख) एक प्रॉक्सी हैंडलर (setHandler)

दो उत्तरार्द्ध तरीकों के नाम Javassist द्वारा hardcoded और ProxyObject इंटरफ़ेस का प्रतिनिधित्व कर रहे निर्धारित किया है। यदि अब आप प्रॉक्सी क्लास का प्रॉक्सी क्लास बनाते हैं, तो जावस्सिस्ट ProxyObject की विधियों को दो बार बनाने का शेड्यूल करेगा। एक बार पहली स्थिति और एक बार दूसरी स्थिति से।

आप MethodFilter सेट करके इसे से बच सकते हैं जो ProxyObject के तरीकों को ओवरराइड करने के लिए निर्दिष्ट नहीं करता है जैसे कि जावस्सिस्ट केवल दूसरी स्थिति द्वारा विधियों को बनाएगा। हालांकि, इसका मतलब यह होगा कि आप सुपर क्लास प्रॉक्सी के लिए ProxyObject को प्रतिबिंब के माध्यम से सीधे संबंधित फ़ील्ड तक पहुंचने के बिना सेट नहीं कर पाएंगे। इसलिए, आपका दृष्टिकोण शायद सबसे साफ है।

cglib प्रति वर्ग कॉलबैक परिभाषित करता है और उदाहरण के लिए नहीं कि इस समस्या को cglib के साथ थोड़ा अलग है लेकिन परिणामस्वरूप एक और संघर्ष होता है।

हालांकि, यदि आप प्रॉक्सी कक्षाएं बनाना चाहते हैं जो इन कमियों को पीड़ित नहीं करते हैं, तो आपको मेरी लाइब्रेरी Byte Buddy में दिलचस्पी हो सकती है जिसे मैंने कोनेब और जावस्सिस्ट के साथ कोने के मामलों में काम करते समय निराश होने के बाद लिखा था। यदि आप रनटाइम कोड पीढ़ी के साथ काम कर रहे हैं तो मुझे आशा है कि इससे आपको कुछ लचीलापन प्रदान करने में मदद मिलेगी जो अन्य पुस्तकालयों की कमी है।