2012-07-18 25 views
6

मुझे अपने वर्ग के प्रकार के माध्यम से सेम देखने की जरूरत है। जब बीन्स को प्रॉक्सी द्वारा लपेटा जाता है (कुछ विधियां @ ट्रांसेक्शनल होती हैं) - InvatoinContext उन्हें ढूंढने में विफल रहता है। मुझे लगता है कि अगर मैं उन्हें एक इंटरफ़ेस के माध्यम से देखता हूं, तो यह काम करता है लेकिन इस मामले में मैं एक ठोस वर्ग प्रकार के साथ काम कर रहा हूं। मुझे पता है कि बीन उस प्रकार का है जिसे मैं ढूंढ रहा हूं लेकिन getBean() विधि विफल हो जाती है।स्प्रिंग एप्लिकेशन कॉन्टेक्स्ट.getBean (कक्षा सी) प्रॉक्सी कक्षाओं के लिए काम नहीं कर रहा है

मैं वसंत के सार BeanFactory कोड में समस्या को डीबग (और ठीक) कर सकता हूं। मुद्दा यह है कि यह बीन इंस्टेंस के प्रकार की जांच करता है जिसका मैं अनुरोध कर रहा हूं लेकिन beanInstance.getClass() एक प्रॉक्सी है। सारबीन फैक्ट्री को इसके लिए क्षतिपूर्ति करनी चाहिए और प्रकार की तुलना प्रॉक्सी के लक्ष्य वर्ग से करें।

मेरे पास इसके लिए एक फिक्स है लेकिन मैं विशेष रूप से वसंत के एक पैच किए गए संस्करण का उपयोग नहीं करना चाहता हूं और मुझे संदेह है कि यह कुछ काम करने के लिए कॉन्फ़िगर किया जा सकता है, या यह वास्तव में एक बग है?

उत्तर

11

स्प्रिंग इंटरफ़ेस या CGLIB का उपयोग करके स्प्रिंग लागू करने के दो प्रमुख तरीके हैं (उदा। @Transactional समर्थन): या तो प्रॉक्सी इंटरफेस या CGLIB का उपयोग करके।

इंटरफ़ेस (डिफ़ॉल्ट) के साथ यदि आपकी कक्षा किसी भी इंटरफेस लागू करती है, तो वसंत सभी इंटरफेस को लागू करने वाली प्रॉक्सी बना देगा। अब से आप केवल उस इंटरफेस के माध्यम से अपने बीन के साथ काम कर सकते हैं। आपकी कक्षा उनके अंदर गहरी दुखी है।

आप लक्ष्य वर्गों को प्रॉक्सी के माध्यम से बजाय सक्षम करते हैं:

<aop:config proxy-target-class="true"> 

स्प्रिंग एक उपवर्ग (obvoiusly अभी भी अपने सभी इंटरफेस को लागू करने) के बजाय का निर्माण करेगा। यह आपकी समस्या को ठीक करेगा। हालांकि याद रखें कि लौटाई वस्तु वास्तव में आपकी कक्षा नहीं है बल्कि गतिशील रूप से जेनरेट की गई उप-वर्ग है जो आपके मूल ऑब्जेक्ट को लपेटती है और प्रतिनिधि करती है। ज्यादातर मामलों में यह कोई समस्या नहीं होनी चाहिए।

और नहीं, बेशक यह एक बग नहीं है लेकिन जाने-माने व्यवहार है और नहीं, वसंत पैच करने की कोई आवश्यकता नहीं है।

भी देखें

+0

स्पष्टीकरण के लिए धन्यवाद - मुझे पता चला कि मैं एक इंटरफ़ेस के माध्यम से अपना बीन पुनर्प्राप्त कर सकता हूं। मैंने इसका उपयोग करने के बारे में सोचा लेकिन समस्या यह है कि मुझे पूरी तरह से मेरी स्थिति में ठोस वर्ग को संदर्भित करने की आवश्यकता है (कंक्रीट क्लास भी एक और इंटरफ़ेस लागू करता है जिस पर मैं भरोसा कर रहा हूं)। मैं इस निष्कर्ष पर आया कि मैं आज इसके आसपास काम करने के लिए जीसीएलआईबी विकल्प का उपयोग करूंगा। कोई इसका उपयोग क्यों नहीं करना चाहेंगे? प्रॉक्सी कक्षाओं का उपयोग करने के लिए, यह मेरे लिए एक बग की तरह गंध करता है, न कि 'फीचर'! –

+0

@AlexWorden: यदि आपकी कक्षा कई इंटरफेस लागू करती है तो आप उनमें से किसी भी द्वारा बीन ला सकते हैं। CGLIB के नुकसान में से एक यह है कि ... आपको CGLIB (बाहरी पुस्तकालय) का उपयोग करना होगा। खैर, यह न तो एक बग है और न ही एक विशेषता है - वसंत को किसी भी तरह एओपी लागू करना है और ये दो सबसे आम विशेषताएं हैं। इसके अलावा सीजीएलआईबी के पास अन्य दुष्प्रभाव होते हैं जैसे कि आपकी कक्षा के दो उदाहरण एक के बजाय। एक टिप्पणी के लिए दो बहुत कुछ –

1
<context:component-scan base-package="<Your base package name goes here>" /> 
<aop:aspectj-autoproxy /> 
<aop:config proxy-target-class="true"/> 

applicationContext.xml इस में इन तीन पंक्तियां लिखें मेरे लिए काम किया