2012-02-28 9 views
7

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

यहाँ इस आशय का प्रदर्शन करने की एक न्यूनतम कोड है, सादगी के लिए @Value इस्तेमाल किया, लेकिन यह @Autowired के साथ एक ही है:

import org.springframework.beans.factory.annotation.Value; 

import javax.annotation.PostConstruct; 

public class AutowireTest { 
    public String testField; 

    @PostConstruct 
    public void init() { 
    if (testField == null) 
     throw new RuntimeException("FAIL"); 
    } 

    @Value("default") 
    public void setTestField(String testField) { 
    this.testField = testField; 
    } 
} 

और वसंत config:

<bean id="au_test1" class="AutowireTest"> 
    <property name="testField" value="manual"/> 
</bean> 

<bean id="au_test2" class="AutowireTest"/> 

अगर मैं <property name="testField" value="manual"/>, दोनों सेम को दूर "डिफ़ॉल्ट" प्राप्त करें। यदि यह दूसरा बीन अपवाद फेंकता है। मैंने वसंत कोड पर एक नज़र डाली और AutowiredAnnotationBeanPostProcessor इंजेक्शन मेटाडाटा कैश का उपयोग कर रहा है जहां वर्ग इंजेक्शन मेटाडेटा के लिए कुंजी हैं जिसका मतलब है कि एक बीन के लिए विशेष संपत्ति को अन्य उदाहरणों के लिए ऑटोवॉयरिंग अक्षम करता है।

कोई विचार यह क्यों है? मैं एक समान प्रभाव कैसे प्राप्त कर सकता हूं जो आवश्यक रूप से स्ट्रिंग मानों के लिए काम नहीं कर रहा है बल्कि ऑब्जेक्ट सेम के लिए भी?

संपादित करें: मैं एक ऐसी संपत्ति चाहता हूं जहां कई मिलान करने वाले उम्मीदवार हों। एक को primary के रूप में चिह्नित किया गया है। जब तक मैं एक्सएमएल के माध्यम से मैन्युअल रूप से उम्मीदवार निर्दिष्ट नहीं करता, मैं प्राथमिक वायर्ड को रखना चाहता हूं। मेरा मूल दृष्टिकोण इस संपत्ति के लिए @Autowired का उपयोग करना था, लेकिन चूंकि यह काम नहीं करता है, इसलिए मैं एक विकल्प की तलाश में हूं। किसी कारण से मैं बीन विरासत का उपयोग नहीं करना चाहता।

EDIT2: यदि मैं इन दो बीन परिभाषाओं को स्वैप करता हूं, तो समस्या नहीं होती है। पहली बार मैन्युअल ओवरराइड का पता चला है जब तक संपत्ति स्वचालित रूप से ठीक हो जाती है। इसका मतलब है कि यह एक इरादा विशेषता नहीं है क्योंकि इससे कुछ परियोजनाओं में बग का पता लगाने के लिए अजीब और कठिन हो सकता है, जिनकी अपेक्षाओं के अनुसार वायर्ड नहीं किया जा रहा है।

+1

मुझे लगता है कि बेहतर प्रदर्शन प्रदान करने के लिए कार्यान्वयन इस तरह से है। –

+0

मैंने इस मुद्दे को प्रदर्शित करने वाली एक न्यूनतम परियोजना के साथ वसंत जिरा में सबमिट किया है: https://jira.springsource.org/browse/SPR-9183 – mrembisz

उत्तर

0

का उपयोग कर मेरी राय में यह वसंत ऋतु में एक बग जो मैं jira माध्यम से सबमिट की है अन्य बीन्स में उन्हें इंजेक्षन कर सकते हैं। इसके आसपास काम करने के लिए, एनोटेशन को सेटर से फ़ील्ड में ले जाना चाहिए। संपत्ति के मैन्युअल ओवरराइडिंग की अनुमति देने के लिए सेटटर को अवश्य ही रहना चाहिए। संभावित सेटर तर्क (मुझे पता है कि इससे बचा जाना चाहिए) @PostConstruct पर ले जाया जाना चाहिए।नीचे मूल कोड अनुकूलित:

import org.springframework.beans.factory.annotation.Value; 

import javax.annotation.PostConstruct; 

public class AutowireTest { 
    @Value("default") 
    public String testField; 

    @PostConstruct 
    public void init() { 
    if (testField == null) 
     throw new RuntimeException("FAIL"); 
    } 

    public void setTestField(String testField) { 
    this.testField = testField; 
    } 
} 
1

आप AutowiredAnnotationBeanPostProcessor के लिए Javadocs पर एक नज़र डालें, तो एक टिप्पणी करते हुए कहा है:

"एनोटेशन इंजेक्शन एक्सएमएल इंजेक्शन से पहले प्रदर्शन किया जाएगा, इस प्रकार बाद विन्यास तार संपत्तियों के लिए पूर्व स्थान पर आ जाएगी दोनों दृष्टिकोणों के माध्यम से। "

इसका मतलब है कि "टेस्टफिल्ड" के लिए संपत्ति मूल्य के साथ एक्सएमएल में अपनी बीन्स संपत्ति को सेट करना और दो नए बीन्स बनाता है जहां testField सेट है और जहां यह शून्य है।

यह एक या दूसरी बात है। आप या तो कक्षा के लिए ऑटोवॉयरिंग का उपयोग कर सकते हैं या इसे मैन्युअल रूप से एक्सएमएल में सेट कर सकते हैं लेकिन दोनों को नहीं कर सकते हैं। मैं अनुमान लगाता हूं कि जब आप संपत्ति वसंत को हटाते हैं तो दोनों ही नामों के लिए एक ही ऑटोवायर बीन सेट कर रहे हैं।

एक बार एक ही कक्षा की सेम मैन्युअल स्थापित कर रहे हैं आप @Qualifier("au_test1") एनोटेशन

+0

आपके उत्तर के लिए धन्यवाद। मैंने javadoc पढ़ा लेकिन मैं नहीं देख सकता कि यह कैसे समझाता है कि मैं क्या देखता हूं। इसके अलावा मैंने यह बताने के लिए अपना प्रश्न अपडेट किया है कि मैं क्या हासिल करना चाहता हूं। – mrembisz

+0

मैंने अपने प्रश्न के लिए एक और अद्यतन किया जो बताता है कि इस व्यवहार से बीन्स घोषित किए जाने के क्रम में प्रभावित होता है। मुझे लगता है कि स्पष्ट रूप से इसका मतलब है कि यह एक इच्छित विशेषता के बजाय एक बग है। – mrembisz

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