2010-03-26 12 views
60

क्या वसंत से एक रेफ बीन पर एक विधि को कॉल करने के परिणाम को इंजेक्ट करना संभव है?क्या वसंत से एक रेफ बीन पर एक विधि बुलाए जाने के परिणाम को इंजेक्ट करना संभव है?

मैं दो अलग-अलग परियोजनाओं से एक सामान्य वर्ग में कुछ कट/पेस्ट कोड को दोबारा करने की कोशिश कर रहा हूं। परियोजनाओं में से एक में, कोड एक कक्षा में रहता है जिसे मैं "माई क्लाइंट" कहूंगा जिसे वसंत से तत्काल किया जा रहा है। इसे एक और वसंत-तत्काल वर्ग "माईग्रिस्ट्री" के साथ इंजेक्शन दिया जाता है, फिर माई क्लाइंट क्लास उस कक्षा का उपयोग एंडपॉइंट देखने के लिए करती है। मुझे वास्तव में मेरी रिफैक्टर कक्षा में एंडपॉइंट स्ट्रिंग की ज़रूरत है, जिसे एक सेटर के माध्यम से शुरू किया जा सकता है। मैं वास्तव में रिफैक्टर कोड में MyClient से MyRegistry पर निर्भरता नहीं रख सकता।

तो, मेरा सवाल यह है ... क्या कोई तरीका है कि मैं माइक्रेट्रिस्ट्री कक्षा में देखे गए वसंत से एंडपॉइंट स्ट्रिंग इंजेक्ट कर सकता हूं। तो, मैं वर्तमान में है:

<bean id="registryService" class="foo.MyRegistry"> 
...properties set etc... 
</bean> 

<bean id="MyClient" class="foo.MyClient"> 
    <property name="registry" ref="registryService"/> 
</bean> 

लेकिन मैं करना चाहते हैं (और मैं जानता हूँ कि यह है काल्पनिक स्प्रिंग वाक्य रचना)

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint" value="registryService.getEndPoint('bar')"/> 
</bean> 

जहां MyRegistry एक विधि getEndPoint (Stirng endPointName)

होगा

आशा है कि मैं जो हासिल करने की कोशिश कर रहा हूं उसके दृष्टिकोण से समझ में आता है। वसंत में ऐसा कुछ संभव है तो कृपया मुझे बताएं!

उत्तर

38

सबसे अच्छा समाधान के रूप में @ ChssPly76 द्वारा वर्णित स्प्रिंग 3 की अभिव्यक्ति भाषा का प्रयोग करने के लिए है, लेकिन आप वसंत के एक पुराने संस्करण उपयोग कर रहे हैं, यह लगभग है के रूप में आसान:

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint"> 
     <bean factory-bean="registryService" factory-method="getEndPoint"> 
     <constructor-arg value="bar"/> 
     </bean> 
    </property> 
</bean> 
+1

बहुत अच्छा - और थोड़ा विचलित। हम यहां वसंत 2.5.6 का उपयोग कर रहे हैं इसलिए मैं इस तकनीक का उपयोग करने की कोशिश करूंगा। मैं देखता हूं कि अब आप क्या कर रहे हैं ... आप रजिस्ट्री सेवा पर फैक्ट्री विधि के रूप में getEndPoint() विधि का इलाज करते हैं - "फैक्ट्री-निर्मित" श्रेणी एंडपॉइंट का प्रतिनिधित्व करने वाली एक साधारण स्ट्रिंग है। बहुत ही शांत! मेरी आशा है कि इससे काम हो जाए! –

+3

"ईर्ष्या" वास्तव में, आपको कितना हिम्मत है :) यह बिल्कुल ठीक है कि कैसे 'फैक्ट्री-बीन' और 'फैक्ट्री-विधि' का उपयोग किया जाना चाहिए, मैं आपको जानूंगा :) – skaffman

98

यह Spring Expression Language के माध्यम से वसंत 3.0 में संभव है:

<bean id="registryService" class="foo.MyRegistry"> 
...properties set etc... 
</bean> 

<bean id="MyClient" class="foo.MyClient"> 
    <property name="endPoint" value="#{registryService.getEndPoint('bar')}"/> 
</bean> 
+1

@ ChssPly76 में आपका स्वागत है, आप वापस आ रहे हैं –

+2

यह भयानक है – jarandaf

+2

बहुत भयानक और सिर्फ मैं क्या nee डेड !!!! – nterry

2

या वसंत 2.x में, एक BeanPostProcessor

आमतौर का उपयोग करके, सेम पोस्ट प्रोसेसर सेम गुण की वैधता की जाँच के लिए उपयोग किया जाता है या विशेष मानदंडों के अनुसार बीन गुण (आप क्या चाहते हैं) को बदलना।

public class MyClientBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware { 

    private ApplicationContext applicationContext; 
    public void setApplicationContext(ApplicationContext applicationContext) { 
     this.applicationContext = applicationContext; 
    } 

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
     return bean; 
    } 

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
     if((bean instanceof MyClient)) && (beanName.equals("MyClient"))) { 
      Myregistry registryService = (Myregistry) applicationContext.getBean("registryService"); 

      ((MyClient) bean).setEndPoint(registryService.getEndPoint("bar")); 
     } 

     return bean; 
    } 
} 

और रजिस्टर अपने BeanPostProcessor

<bean class="br.com.somthing.MyClientBeanPostProcessor"/> 
संबंधित मुद्दे