2015-11-06 7 views
18

एनाटेट @ संपत्ति के लिए क्या किया गया है या इसे सेटटर में क्या करना है?वसंत @Autowire संपत्ति बनाम सेटर

जहाँ तक मुझे पता है कि दोनों के पास एक ही परिणाम है, लेकिन क्या किसी दूसरे का उपयोग करने का कोई कारण है?

अद्यतन (अधिक संक्षिप्त होने के लिए)

इस

package com.tutorialspoint; 

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

public class TextEditor { 
    private SpellChecker spellChecker; 

    @Autowired 
    public void setSpellChecker(SpellChecker spellChecker){ 
     this.spellChecker = spellChecker; 
    } 

    public void spellCheck() { 
     spellChecker.checkSpelling(); 
    } 
} 

और इस

package com.tutorialspoint; 

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

public class TextEditor { 
    @Autowired 
    private SpellChecker spellChecker; 

    public TextEditor() { 
     System.out.println("Inside TextEditor constructor."); 
    } 

    public void spellCheck(){ 
     spellChecker.checkSpelling(); 
    } 
} 
+0

मुझे नहीं पता कि इस प्रश्न का उत्तर क्यों माना जाएगा। मैं जानना चाहता हूं कि एक सेटर में या सीधे संपत्ति में @Autowired का उपयोग करने के बीच व्यावहारिक अंतर है या नहीं। यह नहीं पूछ रहा कि कौन सा बेहतर है, अगर कोई फर्क पड़ता है तो – luso

उत्तर

14
@Autowired एनोटेशन के साथ

के बीच एक अंतर है, तो आप एक सेटर की जरूरत नहीं है तरीका। एक बार जब आपका बीन का कन्स्ट्रक्टर ऑब्जेक्ट आवंटित/बनाने के साथ किया जाता है, तो वसंत इस एनोटेशन के लिए स्कैन करेगा और आपके द्वारा एनोटेट किए गए ऑब्जेक्ट उदाहरणों को इंजेक्ट करेगा।

यदि आपके पास सेटटर है और यदि आप अभी भी xml कॉन्फ़िगरेशन का उपयोग कर रहे हैं, तो आप स्पष्ट रूप से गुण सेट करेंगे।

यह कहकर, आप अपने कन्स्ट्रक्टर और सेटर विधि को ऑटोवायर एनोटेशन के साथ एनोटेट कर सकते हैं, जिसे मैं पसंद करूंगा क्योंकि इससे मुझे स्प्रिंग से दूर जाने के लिए लचीलापन मिलेगा (हालांकि मैं इसे नहीं करता)।

+0

वसंत उदाहरणों में जैसा कि मैंने पोस्ट को अपडेट किया था, क्या DI शर्तों में कोई अंतर है? – luso

+0

कोई फर्क नहीं पड़ता, आप अभी भी निर्भरता इंजेक्शन कर रहे हैं। यह सिर्फ कन्स्ट्रक्टर या सेटर द्वारा आपकी पसंद है उदाहरण के लिए – SMA

0

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

संपत्ति और कन्स्ट्रक्टर-Arg सेटिंग्स में स्पष्ट निर्भरता हमेशा ऑटोवॉयरिंग को ओवरराइड करती है। आप प्राइमेटिव्स, स्ट्रिंग्स और क्लासेस (और इस तरह के सरल गुणों के सरणी) जैसे तथाकथित सरल गुणों को स्वत: नहीं कर सकते हैं। यह सीमा डिजाइन द्वारा है।

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

तारों की जानकारी उन उपकरणों के लिए उपलब्ध नहीं हो सकती है जो स्प्रिंग कंटेनर से दस्तावेज़ उत्पन्न कर सकते हैं।

कंटेनर के भीतर एकाधिक बीन परिभाषाएं सेटर विधि या कन्स्ट्रक्टर तर्क द्वारा निर्दिष्ट प्रकार से मेल खाती हैं जो ऑटोवायर होने के लिए होती है। सरणी, संग्रह, या मानचित्र के लिए, यह एक समस्या नहीं है। हालांकि निर्भरताओं के लिए जो एक मूल्य की अपेक्षा करते हैं, इस अस्पष्टता को मनमाने ढंग से हल नहीं किया जाता है। यदि कोई अद्वितीय बीन परिभाषा उपलब्ध नहीं है, तो एक अपवाद फेंक दिया जाता है।

1

यदि आप कर सकते हैं, तो आपको सेटर से बचना चाहिए। अगर आपको इसकी आवश्यकता नहीं है, तो यह बेहतर होगा जब यह अस्तित्व में न हो, है ना? एक final क्षेत्र के साथ, मैं जानता हूँ कि यह कभी नहीं बदलेगा और मैं multithreading visibility guarantee मिलती है:

मैं व्यक्तिगत रूप से Guice मुझे

public class TextEditor { 
    private final SpellChecker spellChecker; 

    @Inject public TextEditor(SpellChecker spellChecker) { 
     this.spellChecker = spellChecker; 
    } 

    public void spellCheck(){ 
     spellChecker.checkSpelling(); 
    } 
} 

लिखने के लिए अनुमति देता है यह एक कदम आगे चला जाता है पसंद करते हैं।

6

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

उन मामलों में, एक सेटर (या कन्स्ट्रक्टर) ऑटोवायर आपको बेहतर तरीके से अनुकूल करेगा। आपके पास अप्रयुक्त क्लास-स्तरीय फ़ील्ड नहीं होंगे।

कंक्रीट उदाहरण: आप RabbitTemplate (एक वस्तु है कि RabbitMQ को संदेश भेजता है) यह निर्माण करने के लिए का निर्माण करने की जरूरत है, तो आप ConnectionFactory http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-

आपको लगता है कि ConnectionFactory स्टोर करने के लिए की जरूरत नहीं है की जरूरत है। उस मामले, कोड है कि इस तरह दिखता है में:

Class MyClass { 
private RabbitTemplate template; 

@Autowired 
void setConnectionFactory(ConnectionFactory c) { 
    template=new RabbitTemplate(c); 
} 
} 

... आप सीधे ConnectionFactory क्षेत्र autowiring की तुलना में बेहतर काम करेगा।

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

0

आप एक संपत्ति पर @Autowired एनोटेशन उपयोग करते हैं, वसंत spring.xml का उपयोग कर संपत्ति आरंभ हो जाएगा। आपको इस मामले में सेटर की आवश्यकता नहीं है।

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

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

class DaoDemo{ 
    //@Autowired 
    //private DataSource dataSource; 
    private JdbcTemplate jdbcTemplate; 

    @Autowired 
    public void setDataSource(DataSource dataSource){ 
    //this.dataSource = dataSource; 
    this.jdbcTemplate = new JdbcTemplate(dataSource); 
    } 

    public int getTableRowCount(){ 
     String sql = "SELECT COUNT(*) FROM DEMOTABLE"; 
     //jdbcTemplate.setDataSource(dataSource); //No need to do this as its done in DataSource Setter now. 
     return jdbcTemplate.queryForObject(sql,Integer.class); 

} 

उपरोक्त कोड में, डेटा स्रोत का ही उपयोग JdbcTemplate में पारित करने के लिए किया गया था। इसलिए, डेटा स्रोत की संपत्ति बनाना यहां समझ में नहीं आता है। तो, बस springSxml से अपनी प्रविष्टि प्राप्त करने के लिए डेटासोर्स बीन के सेटटर विधि पर @Autowired का उपयोग करें और उस विशेष समय पर इसका उपयोग करें।

0

एक ऐसा मामला है जहां एक वैकल्पिक संपत्ति पर @Autowired का उपयोग नहीं किया जाएगा।

यदि आप उस संपत्ति का उपयोग करके कुछ प्रारंभिक करना चाहते हैं, तो इसे कन्स्ट्रक्टर कहने से पहले सेट नहीं किया जा सकता है, और चूंकि यह वैकल्पिक है, तो आप इसे कन्स्ट्रक्टर में तर्क के रूप में नहीं डाल सकते हैं।

उस स्थिति में @Autowired सेटर विधि का उपयोग करना बेहतर है, ताकि संपत्ति स्वचालित होने के बाद आप प्रारंभिक प्रदर्शन कर सकें।

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