2009-11-28 17 views
6

हमारे पास कुछ डोमेन ऑब्जेक्ट्स हैं जो रनटाइम पर बनाई गई हैं - स्प्रिंग द्वारा नहीं। इन डोमेन ऑब्जेक्ट्स को कुछ सेवा प्रकार बीन्स तक पहुंच की आवश्यकता होती है जिन्हें स्प्रिंग द्वारा प्रबंधित किया जा रहा है। रनटाइम एक्सेस पर बनाए गए डोमेन ऑब्जेक्ट्स स्प्रिंग बीन्स गतिशील रूप से (DI द्वारा नहीं) कैसे हो सकते हैं?निर्भरता इंजेक्शन द्वारा वसंत बीन * नहीं * तक पहुंच

उत्तर

7

आपको उन्हें एप्लिकेशन कॉन्टेक्स्ट या बीनफ़ैक्टरी का संदर्भ देना होगा ताकि वे स्प्रिंग-प्रबंधित बीन्स प्राप्त कर सकें।

+1

एक वेब अनुप्रयोग में ऐसा करने के लिए सबसे अच्छा अभ्यास क्या है: आप तो जैसे org.springframework.beans.factory.config.MethodInvokingFactoryBean के माध्यम से यह वसंत के लिए उपलब्ध होगा? क्या यह सामान्य है कि गतिशील रूप से बनाए गए डोमेन ऑब्जेक्ट्स को इस तरह से स्प्रिंग बीन्स तक पहुंच की आवश्यकता है? –

+1

मैं वेब अनुप्रयोग को देखने के लिए अनुशंसा करता हूं: http://static.springsource.org/spring/docs/3.0.0.RC1/javadoc-api/। मुझे लगता है कि स्प्रिंग को सेम का प्रबंधन करना अधिक आम है। विधि कॉल संदर्भ के अंदर केवल स्थानीय बीन्स "नया" का उपयोग करके बनाए जाएंगे। – duffymo

0

आप उस दृष्टिकोण का उपयोग कर सकते हैं जो @ डफिमो ने सुझाव दिया था, लेकिन यदि आप एक वेब ऐप के रूप में वसंत नहीं चला रहे हैं तो आपको इस SO entry पर देखना चाहिए। देखें कि यूटिलिटी क्लास को सबसे लोकप्रिय उत्तर में थ्रेड सुरक्षित बनाया गया है। ओपी बीटीडब्ल्यू और उत्तर आपको जो चाहिए उसे प्राप्त करना चाहिए और फिर आप स्प्रिंग प्रबंधित बीन्स का संदर्भ प्राप्त करने के लिए इस उपयोगिता वर्ग का उपयोग कर सकते हैं।

8

@ डफिमो का उत्तर इस समस्या का सबसे आम समाधान है, और आपको शायद इसका पालन करना चाहिए।

हालांकि, अगर आप ठाठ महसूस कर रहे हैं, और अपनी स्थिति का समर्थन करता है, तो आप वसंत के AspectJ समर्थन का उपयोग कर autowire your non-spring-managed domain objects के लिए वसंत सेम के साथ विचार कर सकते हैं:

[...] शामिल एक एनोटेशन संचालित पहलू जो पर किसी भी ऑब्जेक्ट की निर्भरता इंजेक्शन की अनुमति देने के लिए इस क्षमता का उपयोग करता है। समर्थन के बाहर बनाए गए ऑब्जेक्ट्स के लिए किसी भी कंटेनर के नियंत्रण के लिए किया गया है। डोमेन ऑब्जेक्ट्स अक्सर इस श्रेणी में आते हैं क्योंकि उन्हें अक्सर प्रोग्रामिंग रूप से नए ऑपरेटर का उपयोग करके या किसी ORM टूल द्वारा डेटाबेस क्वेरी के परिणाम के रूप में प्रोग्राम किया जाता है।

यह वूडू, यह सामान पर काम कर रहा है, और यह केवल कुछ ऐप्ससेवर पर काम करता है, लेकिन यह आपके लिए टूल हो सकता है।

3

वसंत में SingletonBeanFactoryLocator नामक एक तंत्र है जिसे आप ईजेबी 2.0 अनुप्रयोगों जैसे स्थानों में उपयोग कर सकते हैं, जहां स्थानों पर बीन फैक्ट्री/एप्लिकेशन संदर्भ प्राप्त करने के लिए आप निर्भरता इंजेक्शन का उपयोग नहीं कर सकते हैं। मौजूदा वसंत ContextLoader में एक हुक है जिसे आप पहले से ही इस कार्यक्षमता का लाभ उठाने के लिए उपयोग कर रहे हैं, हालांकि यह सेटअप करने में कुछ मुश्किल है।

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

<context-param> 
    <param-name>locatorFactorySelector</param-name> 
    <param-value>classpath:beanRefFactory.xml</param-value> 
</context-param> 

<context-param> 
    <param-name>parentContextKey</param-name> 
    <param-value>beanRefFactory</param-value> 
</context-param> 

locatorFactorySelector एक संदर्भ है:

तो फिर आप अपने web.xml के संदर्भ मानकों के एक जोड़े को जोड़ने के लिए (जैसे आप config स्थान के लिए करते हैं) माता-पिता प्रारंभ करने में यह बताने के लिए होगा एक एक्सएमएल फ़ाइल के लिए, लेकिन (यह वह जगह है जहां मैं हमेशा भ्रमित हो जाता हूं) यह आपकी सेवाओं को परिभाषित करने वाले एक्सएमएल को इंगित नहीं करेगा। यह एक बीन परिभाषा xml है जो एक अनुप्रयोग संदर्भ बीन बनाता है। इसके बाद आप parentContextKey विशेषता का उपयोग करके इस बीन का संदर्भ लेंगे।

तो उदाहरण के लिए, बीनआरफ फैक्टरी।एक्सएमएल तो होते हैं:

<beans> 
    <bean id="beanRefFactory" 
     class="org.springframework.context.support.ClassPathXmlApplicationContext"> 
     <constructor-arg> 
      <list> 
       <value>service-context.xml</value> 
      </list> 
     </constructor-arg> 
    </bean> 
</beans> 

अपने गैर मृत्यु हो गई डोमेन वस्तुओं में, आप तो इस कोड के साथ आवेदन संदर्भ के लिए मिल सकता है:

BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); 
    BeanFactoryReference contextRef= locator.useBeanFactory(parentContextKey); 
    ApplicatonContext context = (ApplicationContext) contextRef.getFactory(); 

आप this blog post में ContextSingletonBeanFactoryLocator बारे में अधिक जानकारी पा सकते हैं। Java Development with the Spring Framework में ईजेबी पर अध्याय में इस दृष्टिकोण का उपयोग करने का भी एक अच्छा विवरण है।

0

एक समाधान (BeanLocator देखें।)

अन्य विकल्प एक वैश्विक static विधि है कि वसंत आवेदन प्रतियोगिता रिटर्न उपयोग करने के लिए अपने व्यापार की वस्तुओं ApplicationContextAware इंटरफ़ेस को लागू करने के लिए हो सकता है। तत्कालता में, आपके "एकीकरण" कोड को गतिशील रूप से बनाए गए बीन में स्प्रिंग ApplicationContext को इंजेक्ट करना होगा (शायद यह जांचकर कि कक्षा ApplicationContextAware लागू करती है या नहीं।) यह निश्चित रूप से वसंत के साथ आपके व्यावसायिक कोड को जोड़ देगा, लेकिन पहला विकल्प वही होगा ।

एक भिन्नता ApplicationContext सीधे इंजेक्ट नहीं करेगी लेकिन वसंत @Autowired एनोटेशन का पुन: उपयोग करें। "एकीकरण" कोड तब केवल एनोटेटेड फ़ील्ड इंजेक्ट करेगा।

3

एक फैक्टरी बनाने और वसंत से पंजीकृत करें, बल्कि का उपयोग करने से डोमेन वस्तु बनाने के लिए कारखाने का उपयोग 'नए'

इस मामले में

, आप अपने DomainObjFactory

1

थोड़ा संबंधित question करने के लिए सभी उपहार उपलब्ध

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

यह आपके एप्लिकेशन को स्प्रिंग विशिष्ट इंटरफेस से अनदेखा कर देगा। नीचे दिया गया उदाहरण जेनेरिक के साथ सरलीकृत किया जा सकता है, लेकिन आपको विचार प्राप्त करना चाहिए।

public interface Interceptor { 
    public void onCreate(Object entity); 
} 

public class DomainFactory { 
    public void setInterceptors(List<Interceptor> interceptors) { ... } 
    public Object createInstance() { 
    // iterate interceptors, call onCreate 
    } 
} 

public interface MyServiceAware { 
    public void setMyService(MyService service); 
} 

public class MyServiceInjector implements Interceptor { 
    private MyService myService; 
    public void onCreate(Object entity) { 
    if (entity instanceof MyServiceAware) 
     ((MyServiceAware) entity).setMyService(myService); 
    } 
} 

तो फिर तुम इसे पसंद

<bean id="myServiceInjector" class="MyServiceInjector"> 
    <property name="myService" ref="someServiceBean" /> 
</bean> 

<bean class="DomainFactory"> 
    <property name="interceptors"> 
    <list> 
     <ref bean="myServiceInjector"/> 
    </list> 
    </property> 
</bean> 
0

कुछ कॉन्फ़िगर हैं आप निर्भर वस्तु एक विधि स्थिर getInstance() है कि गैर स्प्रिंग द्वारा इस्तेमाल किया जा सकता डोमेन वस्तुओं में कामयाब साथ एक सिंगलटन बना सकता है।

<bean id="myObject" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="staticMethod"> 
     <value>com.example.MyObject.getInstance</value> 
    </property> 
</bean> 
संबंधित मुद्दे