2010-08-26 9 views
8

मैं वसंत में एक सेम परिभाषा के साथ अच्छी तरह से जाना नहीं है और यह प्रॉक्सी समकक्ष जो हर जगह इस्तेमाल किया जा करने के लिए है है:ApplicationContext.getBean (कक्षा clazz) प्रॉक्सी

<bean name="my.Bean" class="org.springframework.aop.framework.ProxyFactoryBean" scope="prototype"> 
    <property name="proxyInterfaces" value="my.Interface"/> 
    <property name="target" ref="my.BeanTarget"/> 
    <property name="interceptorNames"> 
    <list> 
     <value>someInterceptor</value> 
    </list> 
    </property> 
</bean> 

<bean name="my.BeanTarget" class="my.InterfaceImpl" scope="prototype"> 
    <property name="foo" ref="bar"/> 
</bean> 

यह सब अच्छी तरह से काम करता है; और पूर्व वसंत v3 दुनिया में मैं जैसे

ApplicationContext ctx = ...; 
my.Interface foo = (my.Interface) ctx.getBean("my.Bean"); // cast is necessary 

स्प्रिंग 3 में यह प्रकार सुरक्षित लुकअप करने के लिए संभव हो गया है कि यह उपयोग कर रहा था, जैसे:

my.Interface foo = ctx.getBean(my.Interface.class); 

फिर, यह साधारण सेम के लिए अच्छी तरह से काम करता है के लिए है, जबकि प्रॉक्सिड बीन्स मुझे my.Bean के बजाय my.BeanTarget मिल रहा है। मैं my.BeanTarget इनलाइन करने के लिए इसे छिपा बनाने के लिए (के रूप में वसंत दस्तावेज में दिखाया गया है) की कोशिश की है, लेकिन सभी मुझे मिल गया

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [my.Interface] is defined: expected single bean but found 0: 

तो यह प्रॉक्सी सेम के साथ प्रकार सुरक्षित सेम लुकअप उपयोग करना संभव है और हाँ अगर था - कैसे?

+0

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

+0

हमारी प्रणाली काफी व्यापक है और कुछ बिट्स और कक्षाएं वसंत में पैदा नहीं होती हैं (न ही यह हो सकती है), इसलिए उन्हें आवश्यक निर्भरताओं के लिए बीनफैक्टरी/एपीसीटीएक्स का उपयोग करना होगा। – mindas

उत्तर

6

समस्या यहाँ ProxyFactoryBean पर scope="prototype" है।

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

ProxyFactoryBean के मामले में, जेनरेट प्रॉक्सी का प्रकार जटिल तर्क द्वारा निर्धारित किया जाता है जिसके लिए बीन को पूरी तरह से प्रारंभ करने की आवश्यकता होती है। उस प्रारंभिकरण के बिना, ProxyFactoryBean केवल लक्ष्य प्रकार को null के रूप में रिपोर्ट कर सकता है।

मैं इस के चारों ओर एक तरह से, एक सिंगलटन सेम परिभाषा उदा का उपयोग कर, या स्पष्ट रूप से नाम से सेम के लिए पूछ, के अलावा अन्य नहीं कह सकता

<bean id="my.Interface"> class="ProxyFactoryBean"... > 

और उसके बाद:

ctx.getBean(MyInterface.class.getName()); 

यहाँ, हम सेम नाम इंटरफेस वे लागू होने के सम्मेलन का उपयोग करें।

1

क्या आप my.Interface foo = ctx.getBean(my.Bean.class); नहीं बना सकते?

2

यह ProxyFactoryBean द्वारा बनाई गई प्रॉक्सी के दायरे की तरह लग रहा scope विशेषता के बजाय singleton संपत्ति का उपयोग कर निर्दिष्ट किया जाना चाहिए:

<bean name="my.Bean" class="org.springframework.aop.framework.ProxyFactoryBean"> 
    <property name="singleton" value="false"/> 
    ... 
</bean> 

यह समस्या हल हो जब लक्ष्य सेम आंतरिक है।

आप एक ही कक्षा के कई शीर्ष स्तर के सेम है, तो आप आईडी से एक प्रकार सुरक्षित देखने का उपयोग कर सकते हैं:

my.Interface foo = ctx.getBean("my.Bean", my.Interface.class); 
+0

मैंने इस उत्तर को बहुत जल्दी स्वीकार कर लिया। यह पता चला है कि सिंगलटन = झूठी संपत्ति स्कोप = प्रोटोटाइप जैसी ही नहीं है। मैं सिंगलटन बीन्स प्राप्त करने में कामयाब रहा हूं जो लक्ष्य प्रॉक्सी में लिपटे हैं, भले ही सिंगलटन = झूठा निर्दिष्ट किया गया हो। skaffman का जवाब वास्तव में सच के करीब है। – mindas

+0

इस 'getBean (स्ट्रिंग, कक्षा)' में स्ट्रिंग तर्क क्या है? क्या आप समझा सकते हैं? – Freakyuser

+0

यह एप्लिकेशन संदर्भ में अनुरोधित बीन का नाम है। यह XML कॉन्फ़िगरेशन में 'id' या' name' विशेषता से मेल खाता है। – axtavt

0

स्प्रिंग इंटरफेस के साथ काम करता है, aop के संदर्भ में, आप इंटरफेस के अलग सेट को परिभाषित करने और एक जैसा कि आप उम्मीद अनुरोध कर सकता है। इस तरह से नहीं डाली एक असली वर्ग के लिए की आवश्यकता होगी, लेकिन वसंत इंटरफेस का प्रबंधन करेगा।

मान लें कि आपके पास कक्षा ए लागू है बी। आप ए से बी डालना चाहते हैं लेकिन इसे अस्वीकार कर दिया गया है क्योंकि एओ के कारण प्रॉक्सी है। फिर ए लागू करता है सी और सी विस्तार करता है बी सी आवश्यक विधियों का मालिक है, और सी निजी कार्यान्वयन केवल आपके कार्यान्वयन कोड से ही उपयोग किया जाता है। अंततः वसंत से आपकी उम्मीदों के आधार पर बी या सी इंजेक्ट करने के लिए कहें।

PrivateItf executor = context.getBean(PrivateItf.class); 

इस तरह, असली कक्षा एक प्रॉक्सी है, भले ही यह आपकी निजी इंटरफ़ेस को आपकी ज़रूरत के साथ लागू करे।

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