2010-01-29 20 views
29

पर सेट करना मैं अपने जावा एप्लिकेशन में जेएमएस कनेक्शन फैक्ट्री इंजेक्ट करने के लिए वसंत का उपयोग कर रहा हूं। चूंकि इस कारखाने को केवल उत्पादन वातावरण के भीतर ही जरूरी है, हालांकि मैं विकासशील नहीं हूं, लेकिन मैंने बीन परिभाषा को एक अलग एक्सएमएल में रखा है जिसे मैं अपने मुख्य एप्लिकेशनकॉन्टेक्स्ट.एक्सएमएल में शामिल करता हूं। उत्पादन वातावरण में इस अतिरिक्त फ़ाइल में नियमित बीन परिभाषा होती है। मेरे स्थानीय देव पर्यावरण में मैं इस बीन को शून्य होना चाहता हूं। बीन परिभाषा को आसानी से हटाने की कोशिश कर रहे सभी चीजों को स्पष्ट रूप से एक त्रुटि हुई जब वसंत एक संदर्भ आईडी में आया, जिसे यह नहीं पता था।जानबूझकर स्प्रिंग बीन को

तो मैंने एक फैक्ट्री बीन बनाने की कोशिश की जो आसानी से शून्य हो जाएगी। यदि मैं ऐसा करता हूं, तो स्प्रिंग (2.5.एक्स) शिकायत करता है कि फैक्ट्रीबीन इंटरफ़ेस के स्प्रिंग एपीआई दस्तावेज़ के आधार पर कारखाना शून्य हो गया है, मुझे उम्मीद है कि यह काम करे (देखें Spring API doc)।

<bean id="jmsConnectionFactoryFactory" class="de.airlinesim.jms.NullJmsConnectionFactoryFactory" /> 

<bean id="jmsConnectionFactory" factory-bean="jmsConnectionFactoryFactory" factory-method="getObject"/> 

क्या ऐसा करने का "सही" तरीका होगा:

एक्सएमएल कुछ इस तरह लग रहा है?

उत्तर

20

factory-bean/factory-methodnull साथ काम नहीं करता है, लेकिन एक कस्टम FactoryBean कार्यान्वयन ठीक काम करता है:

public class NullFactoryBean implements FactoryBean<Void> { 

    public Void getObject() throws Exception { 
     return null; 
    } 

    public Class<? extends Void> getObjectType() { 
     return null; 
    } 

    public boolean isSingleton() { 
     return true; 
    } 
} 
<bean id="jmsConnectionFactory" class = "com.sample.NullFactoryBean" /> 
+6

इसके लिए एक खुला सुविधा अनुरोध है, लेकिन वहां 2 साल तक बैठा है ... इसके लिए वोटिंग मदद कर सकती है: http://jira.springframework.org/browse/SPR-5320 – skaffman

+0

यह मेरे लिए काम नहीं करता है अगर मैं एक '@ Autowired' संदर्भ में बीन का इस्तेमाल किया। –

+0

अगर मैं शून्य लौटाता हूं तो मुझे बीनक्रिएशन अपवाद प्राप्त होता है। के कारण: org.springframework.beans.factory.BeanCreationException: कक्षा पथ संसाधन [XXX.xml] में परिभाषित नाम 'nullObject' नाम से बीन बनाने में त्रुटि: फैक्ट्री-बीन 'नल फैक्ट्रीबीन' शून्य – endless

-1

क्या आप विशेष <null> बीन तत्व का उपयोग कर सकते हैं? जैसे

<bean class="ExampleBean"> 
<property name="email"><null/></property> 
</bean> 
the doc से

, खंड 3.3.2.5

+1

यह शायद जब अंतिम आवेदन सेम की प्रॉपर्टी की स्थापना काम करेगा। लेकिन इस बिंदु पर मैं केवल संदर्भ आईडी "jmsConnectionFactory" प्रदान करता हूं जिसे तब वास्तविक बीन या शून्य (यदि यह संभव है तो) को संदर्भित करना चाहिए। – Lunikon

27

मैं बहुत हूँ सुनिश्चित करें कि वसंत आपको बीन आईडी या उपनाम के साथ null को जोड़ने की अनुमति नहीं देगा। आप गुणों को शून्य पर सेट करके इसे संभाल सकते हैं।

यहाँ आप कैसे स्प्रिंग 2,5

<bean class="ExampleBean"> 
    <property name="email"><null/></property> 
</bean> 

में ऐसा किया स्प्रिंग 3.0 में, आप भी Spring expression language (SpEL) उपयोग करने में सक्षम होना चाहिए; जैसे

<bean class="ExampleBean"> 
    <property name="email" value="#{ null }"/> 
</bean> 

या किसी स्पेल अभिव्यक्ति है कि null मूल्यांकन करता है।

और अगर आप एक प्लेसहोल्डर विन्यासक उपयोग कर रहे हैं आप संभवतः भी ऐसा कर सकता है:

<bean class="ExampleBean"> 
    <property name="email" value="#{ ${some.prop} }`"/> 
</bean> 

जहां some.prop के रूप में एक संपत्ति फाइल में परिभाषित किया जा सकता है:

some.prop=null 

या

some.prop=some.bean.id 

नोट, मैंने SPEL (अभी तक) का उपयोग नहीं किया है, इसलिए कुछ समस्याएं हो सकती हैं उपरोक्त का ई ...

+1

लौटा, मैं इस समाधान को बहुत पसंद करता हूं; यह एक कस्टम फैक्टरी बीन के निर्माण की आवश्यकता नहीं है – Richard

4

कुछ ऊपर उल्लेखित, एक्स्टैक्ट का उत्तर ऑटोवॉयरिंग संदर्भों में काम नहीं करता है, जहां स्प्रिंग getObjectType() विधि से सही जानकारी पर निर्भर करेगा।

 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [xxxxxxxxxxxxx] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=yyyyyyyyyyyyyyyy)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotatio 

तो यहाँ एक छोटा सा बदलाव है जो उपयोगकर्ताओं को निर्माण पर objectype मजबूर करने के लिए अनुमति देता है शामिल है है: तो आप की तरह त्रुटियों के साथ अंत हो सकता है। एक कन्स्ट्रक्टर-Arg के बजाए एक संपत्ति का उपयोग करना काम नहीं करता क्योंकि वसंत इस संदर्भ में सेम को पूरी तरह से प्रारंभ नहीं करता है।

public class NullFactoryBean implements FactoryBean { 
    private final Class<?> objectType; 

    public NullFactoryBean(Class<?> objectType) { 
     this.objectType = objectType; 
    } 

    @Override 
    public Object getObject() throws Exception { 
     return null; 
    } 

    @Override 
    public Class<?> getObjectType() { 
     return objectType; 
    } 

    @Override 
    public boolean isSingleton() { 
     return false; 
    } 
} 
5

के लिए इस सवाल का आ रहा है किसी को भी, ध्यान रखें कि बस @Autowired टिप्पणी के रूप में वैकल्पिक चाल करना होगा की स्थापना में रखना है (यानी वसंत संदर्भ अशक्त छोड़ देंगे अगर कोई योग्यता सेम पाया जाता है)।

@Autowired(required = false) 
private SomeClass someBean 

ध्यान दें कि आप इस हर जगह सेम करने के लिए होता है संदर्भित है, एक अशक्त-कारखाना बनाने जैसा कि ऊपर उल्लेख से बड़ी परेशानी हो सकता है।

0

परीक्षणों में अशक्त सेम भी इस तरह इंजेक्ट किया जा सकता:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = NullTest.class) 
@Configuration 
public class NullTest { 

    @Bean(name = "em") 
    public IEntityManager em() { return null; } 
    @Bean 
    public PlatformTransactionManager tm() { return null; } 

    @Resource 
    private SomeBean someBean; // this would get em and tm fields autowired to nulls 
संबंधित मुद्दे