स्प्रिंग @ स्वचालित उपयोग


218

वसंत से वायर्ड किए जाने वाले वर्ग में @Autowired का उपयोग करने के पेशेवरों और विपक्ष क्या हैं ?

बस स्पष्ट करने के लिए, मैं विशेष रूप से @Autowired एनोटेशन के बारे में बात कर रहा हूं , एक्सएमएल में ऑटो-वायरिंग नहीं।

मुझे शायद यह समझ में नहीं आता है, लेकिन मेरे लिए यह लगभग एक विरोधी पैटर्न की तरह लगता है - आपकी कक्षाएं इस बात से अवगत होने लगती हैं कि वे केवल POJOs होने के बजाय DI फ्रेम से बंधे हैं। शायद मैं सजा के लिए एक ग्लूटन हूं, लेकिन मुझे सेम के लिए बाहरी एक्सएमएल कॉन्फिग्रेशन होना पसंद है, और मुझे स्पष्ट वाइरिंग करना पसंद है, इसलिए मुझे पता है कि वास्तव में क्या वायर्ड है।


4
मुझे इस विषय में भी दिलचस्पी है - एक्सएमएल के बजाय एनोटेशन के माध्यम से अपने एमवीसी ऐप को कॉन्फ़िगर करने से ऐसा लगता है कि यह "इस URL पर किस वर्ग को मैप किया गया है?" "कौन इसे संभाल रहा है?"। मुझे एक एकल कॉन्फ़िगरेशन स्रोत पसंद है
मैट बी

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

जवाबों:


253

लंबे समय से मेरा मानना ​​था कि xml फ़ाइलों की तरह "केंद्रीकृत, घोषित, विन्यास" होने में एक मूल्य था जिसका हम सभी उपयोग करते थे। तब मुझे एहसास हुआ कि फाइलों में अधिकांश सामान विन्यास नहीं था - यह कभी भी विकास के बाद कभी भी नहीं बदला गया था। तब मुझे एहसास हुआ कि "केंद्रीकृत" का केवल काफी छोटी प्रणालियों में मूल्य है - केवल छोटी प्रणालियों में आप कभी भी एक संपूर्ण फ़ाइल को एक विन्यास फाइल के रूप में देख पाएंगे । और वास्तव में वायरिंग को समग्र रूप से समझने का क्या मूल्य है, जब कोड में निर्भरताओं द्वारा समान "वाइरिंग्स" को ज्यादातर दोहराया जाता है? तो केवल एक चीज जो मैंने रखी है, वह मेटा-डेटा (एनोटेशन) है, जो अभी भी घोषणा की तरह है। ये कभी नहीं कार्यावधि में बदल सकते हैं और वे कर रहे हैं कभी नहीं "कॉन्फ़िगरेशन" डेटा जिसे कोई मक्खी पर बदल देगा - इसलिए मुझे लगता है कि इसे कोड में रखना अच्छा है।

मैं पूर्ण ऑटो-वायरिंग का उपयोग करता हूं जितना मैं कर सकता हूं। मुझे यह पसंद है। जब तक बंदूक-बिंदु पर धमकी नहीं दी जाती, मैं पुरानी शैली के वसंत में वापस नहीं जाऊंगा। @Autowiredसमय के साथ पूरी तरह से पसंद करने के मेरे कारण बदल गए हैं।

अभी मुझे लगता है कि ऑटोरायरिंग का उपयोग करने का सबसे महत्वपूर्ण कारण यह है कि आपके सिस्टम में ट्रैक रखने के लिए एक कम अमूर्त है। "बीन नाम" प्रभावी रूप से चला गया है। यह सेम नाम केवल xml की वजह से मौजूद है। तो अमूर्त अप्रत्यक्ष (जहां आप बीन-नाम "फू" को बीन "बार" में वायर करेंगे) की एक पूरी परत निकल गई है। अब मैं सीधे अपने बीन में "फू" इंटरफ़ेस तार करता हूं, और कार्यान्वयन रन-टाइम प्रोफ़ाइल द्वारा चुना जाता है। यह मुझे निर्भरता और कार्यान्वयन का पता लगाने के लिए कोड के साथ काम करने की अनुमति देता है । जब मैं अपने कोड में एक स्वत: निर्भरता देखता हूं तो मैं अपनी IDE में "कार्यान्वयन पर जाएं" कुंजी दबा सकता हूं और ऊपर ज्ञात कार्यान्वयन की सूची आती है। ज्यादातर मामलों में सिर्फ एक कार्यान्वयन है और मैं सीधे कक्षा में हूं। कर सकते हैं' क्या कार्यान्वयन का उपयोग किया जा रहा है (मेरा दावा है कि विपरीत xml वायरिंग के साथ सच्चाई के करीब है - मज़ेदार कैसे आपका दृष्टिकोण बदलता है!)

अब आप कह सकते हैं कि यह केवल एक बहुत ही सरल परत है, लेकिन अमूर्तता की प्रत्येक परत जिसे हम अपने सिस्टम में जोड़ते हैं, जटिलता बढ़ाती है। मुझे नहीं लगता कि xml ने कभी भी मेरे द्वारा काम किए गए किसी भी सिस्टम में कोई वास्तविक मूल्य जोड़ा है।

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

मैं कहूंगा कि फुल ऑटोवायरिंग स्प्रिंग की रूबी-ऑन-रेल है: यह इस धारणा को गले लगाता है कि एक सामान्य और सामान्य उपयोग पैटर्न है जो अधिकांश मामलों का उपयोग करते हैं। XML कॉन्फ़िगरेशन के साथ आप बहुत सारे सुसंगत / असंगत कॉन्फ़िगरेशन उपयोग की अनुमति देते हैं जो कि इरादा नहीं हो सकता है। मैंने देखा है कि xml कॉन्फ़िगरेशन विसंगतियों के साथ ओवरबोर्ड जाता है - क्या यह कोड के साथ एक साथ रिफैक्ट हो जाता है? सोचा नहीं। क्या वे विविधताएं एक कारण के लिए हैं? आमतौर पर नहीं।

हम अपने कॉन्फ़िगरेशन में क्वालीफायर का उपयोग शायद ही करते हैं, और इन स्थितियों को हल करने के लिए अन्य तरीके ढूंढते हैं। यह एक स्पष्ट "नुकसान" है जिसका हम सामना करते हैं: हमने ऑटोरायरिंग के साथ चिकनी बातचीत करने के लिए कोड को थोड़ा बदल दिया है: ग्राहक रिपॉजिटरी अब सामान्य Repository<Customer>इंटरफ़ेस को लागू नहीं करता है, लेकिन हम एक इंटरफ़ेस बनाते हैं CustomerRepositoryजो विस्तारित होता है Repository<Customer>। कभी-कभी एक चाल या दो भी होती है जब यह उपवर्ग की बात आती है। लेकिन यह आमतौर पर हमें मजबूत टाइपिंग की दिशा में इंगित करता है, जो मुझे लगता है कि लगभग हमेशा एक बेहतर समाधान है।

लेकिन हां, आप DI की एक विशेष शैली से जुड़ रहे हैं जो ज्यादातर वसंत करता है। हम किसी भी अधिक निर्भरता के लिए सार्वजनिक बसावट नहीं करते हैं (ताकि आप तर्क कर सकें कि हम एनकैप्सुलेशन / सूचना छिपाने वाले विभाग में +1 हैं) हमारे सिस्टम में अभी भी कुछ xml हैं, लेकिन xml में मूल रूप से केवल विसंगतियाँ हैं। पूर्ण autowiring xml के साथ अच्छी तरह से एकीकृत करता है।

अभी हमें केवल एक चीज की आवश्यकता है @Component, @Autowiredऔर शेष को JSR (जैसे JSR-250 ) में शामिल किया जाना है , इसलिए हमें वसंत के साथ टाई करने की आवश्यकता नहीं है। इस तरह से चीजें अतीत में होती रही हैं ( java.util.concurrentसामानों को ध्यान में रखते हुए), इसलिए मैं पूरी तरह से आश्चर्यचकित नहीं होता अगर यह फिर से हुआ।


5
Javax.annotation / javax.inject को वसंत द्वारा समर्थित किया जाता है, ताकि आपके पास वसंत पर कोड निर्भरता न हो।
माइकल विल्स

26

मेरे लिए यहां वह है जो मुझे स्प्रिंग / ऑटो-वायरिंग के बारे में पसंद / नापसंद है।

पेशेवरों:

  • ऑटो-वायरिंग से गंदा XML कॉन्फ़िगरेशन से छुटकारा मिलता है।
  • एनोटेशन का उपयोग करने के लिए बहुत आसान है जो आपको खेतों, सेटर विधियों, या कंस्ट्रक्टरों का उपयोग करके सीधे इंजेक्ट करने की अनुमति देता है। इसके अलावा, आप एनोटेट और अपने इंजेक्शन सेम को 'अर्हता प्राप्त' करने की अनुमति देता है।

विपक्ष:

  • ऑटो-वायरिंग और एनोटेशन का उपयोग करना आपको स्प्रिंग लाइब्रेरी पर निर्भर करता है, जहां एक्सएमएल कॉन्फ़िगरेशन के साथ आप स्प्रिंग के साथ या उसके बिना चलना चुन सकते हैं। जैसा आपने कहा, आप एक डीआई फ्रेमवर्क से बंधे हुए हैं।
  • उसी समय मुझे बीन्स को 'क्वालिफाई' करने में सक्षम होना पसंद है, मेरे लिए यह कोड को वास्तव में गड़बड़ कर देता है। यदि आपको एक ही बीन को कई स्थानों पर इंजेक्ट करने की आवश्यकता है, तो मैंने एक ही स्ट्रिंग नाम दोहराया है। मेरे लिए यह त्रुटियों की संभावना है।

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

मुझे लगता है कि ऑटो-वायरिंग एक अधिग्रहीत स्वाद है, एक बार जब आपको इसकी आदत पड़ जाती है तो आपको एहसास होता है कि एक्सएमएल कॉन्फ़िगरेशन की तुलना में यह कितना शक्तिशाली, आसान और कम सिरदर्द वाला काम है।


3
यदि आप नि: शुल्क स्प्रिंग्स सोर्स टूल का उपयोग करते हैं तो एक्सएमएल कॉन्फ़िगरेशन बहुत कम बुरा हो जाता है, जिसमें ऑटोकोम्प्लीमेंटेशन, बीन ग्राफ्स आदि शामिल हैं
सीन पैट्रिक फ्लॉयड

मैं पूरी तरह से ऑटो-वायरिंग में गड़बड़ और वसंत पुस्तकालयों पर निर्भर होने पर आपसे सहमत हूँ! मैंने XML कॉन्फिगरेशन का उपयोग कभी नहीं किया है और सोच रहा हूं कि शायद मुझे उस रास्ते पर जाना चाहिए?
जेम्स ११

15

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


1
मैंने पाया है कि आंशिक संदर्भों को शुरू करने के लिए javaconfig भी एक बेहतर समाधान हो सकता है, जो कि एक बड़ी जीत है। लेकिन आप कंस्ट्रक्टर्स पर @ ऑटोवर्ड / @ इंजेक्ट (दूसरे शब्दों में, कंस्ट्रक्शन इंजेक्शन पर स्विच) का उपयोग करके इन्हें काफी आसानी से जोड़ सकते हैं।
krosenvold

6

स्विचिंग वातावरण के बारे में बहुत कम चर्चा हुई है। जिन परियोजनाओं पर मैंने काम किया है, उन सभी पर निर्भर करता है कि हम जिस पर्यावरण पर काम कर रहे हैं, उसके आधार पर निर्भरता को इंजेक्ट करना एक वास्तविक मुद्दा है। एक्सएमएल कॉन्फिग के साथ यह स्प्रिंग ईएल के साथ बहुत सीधा है, और मुझे एनोटेशन के साथ किसी भी अच्छे समाधान के बारे में पता नहीं है। मैंने अभी एक पता लगाया है:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

यह काम करना चाहिए, लेकिन एक अच्छा समाधान नहीं है।


मैं इस बारे में एक अलग थ्रेड खोला, और वहाँ वसंत के साथ एक समाधान है @Profilesऔर @Configuration: blog.springsource.org/2011/02/14/... भी देखें अन्य धागा: stackoverflow.com/questions/13490393/...
BTakacs

4

मैंने @Autowire पर स्विच किया है। एक छोटे प्रोजेक्ट के अलावा किसी अन्य चीज़ पर एक्सएमएल कॉन्फ़िगरेशन को बनाए रखना अपने आप में सही और समझ में आने वाला काम है।

IntelliJ स्प्रिंग एनोटेशन के लिए अच्छा (संपूर्ण नहीं) समर्थन प्रदान करता है।


3

इस विषय पर मेरा विचार यह है कि, xml कॉन्फ़िगरेशन कोड की स्पष्टता को कम करता है, विशेष रूप से बड़ी प्रणालियों में।

@Component जैसी टिप्पणियों से चीजें और भी खराब हो जाती हैं। यह डिवेलपर्स को म्यूट करने के लिए डेवलपर्स को स्टीयर करता है, क्योंकि डिपेंडेंसी को अब और अंतिम नहीं बनाया जा सकता है, यह देखते हुए कि डिफॉल्ट कंस्ट्रक्टर को प्रदान करने की आवश्यकता होती है। निर्भरता को या तो सार्वजनिक सेटर के माध्यम से इंजेक्ट किया जाना चाहिए, या @Autowired के माध्यम से अनियंत्रित। [इससे भी बदतर निर्भरता इंजेक्शन कक्षाओं के साथ समझौता किया जाता है जो उनकी निर्भरता को तुरंत बढ़ाते हैं, मैं अभी भी इसे नए लिखित कोड में देखता हूं!]। अनियंत्रित से मेरा मतलब है, बड़ी प्रणालियों में, जब प्रकार के कई कार्यान्वयन (या बच्चे) उपलब्ध होते हैं, तो यह समझने के लिए बहुत अधिक शामिल हो जाता है कि कौन सा कार्यान्वयन @Autowired था, जो एक जांच को बहुत कठिन बना देता है। इसका अर्थ यह भी है कि, आपके पास परीक्षण वातावरण के लिए एक प्रोफ़ाइल है और दूसरा उत्पादन के लिए,

मैं मध्य मैदान से चिपकता हूँ जहाँ मैं अपने विन्यास वर्ग (तों) की घोषणा करता हूँ, (जावा आधारित वसंत विन्यास का उपयोग कर रहा हूँ @ विन्यास)

मैं अपने सभी बीन्स को स्पष्ट रूप से कॉन्फ़िगरेशन क्लास (तों) में घोषित करता हूं। मैं केवल कॉन्फ़िगरेशन वर्ग (एस) में @ उपयोग करता हूं, इसका उद्देश्य कॉन्फ़िगरेशन क्लास के लिए स्प्रिंग पर निर्भरता को सीमित करना है

@Configuration एक विशिष्ट पैकेज में रहता है, यह एकमात्र स्थान है जहां स्प्रिंग स्कैन चलता है। (यह बड़ी परियोजनाओं में काफी तेजी से शुरू होने वाला समय है)

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

निर्मित होने के बाद वस्तुओं को बदलने की संभावनाओं को कम करना, बड़ी प्रणाली में बग्स को काफी हद तक कम कर देता है और साथ ही एक बग को खोजने के लिए समय कम कर देता है।

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


1

यहाँ कुछ अनुभव
पेशेवरों के हैं

  • कॉन्फ़िगर करने के लिए आसान बनाता है क्योंकि हम सिर्फ @Autowire एनोटेशन का उपयोग कर सकते हैं
  • सेटर विधियों का उपयोग नहीं करना चाहते हैं, इसलिए कक्षा अधिक साफ होगी

विपक्ष

  • भले ही हम DI का उपयोग कर रहे हों, कसकर युगल से xml फ़ाइल
  • कार्यान्वयन ढूंढना मुश्किल है (लेकिन अगर आप इंटेलीज की तरह अच्छी आईडी का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप इससे छुटकारा पा सकते हैं)

मेरे व्यक्तिगत अनुभवों के अनुसार मैंने @AutoWire एनोटेशन का उपयोग नहीं किया, लेकिन परीक्षण मामलों में।


1

मुझे XML के बजाय एनोटेशन के साथ लिखना बहुत पसंद है। स्प्रिंग मैनुअल और पिछले संस्करणों के अनुसार, XML और एनोटेशन ने एक ही परिणाम हासिल किया।

यह मेरी सूची है

समर्थक:

  • Xml से बेकार लाइन हटा दें
  • डिबगिंग कोड को सरल बनाएं: जब आप एक क्लास खोलते हैं, तो आप पढ़ सकते हैं कि आपके पास क्लास में क्या है
  • अधिक तेजी से विकासशील, एक्सएमएल की 400 या अधिक लाइन के साथ एक परियोजना पठनीय है?

विपक्ष:

  • मानक जावा कार्यान्वयन नहीं है, लेकिन आप @Inject का उपयोग करने के लिए स्विच कर सकते हैं, जो एक जावा मानक Api है, इसलिए बीन एक पूजो बने रहेंगे
  • आप बस हर जगह का उपयोग नहीं कर सकते हैं, db कनेक्शन ई पर ऐसा है, लेकिन यह केवल एक राय है, मैं एक जगह है जहाँ सभी विन्यास पढ़ा पसंद करते हैं।

0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.