2011-03-25 14 views
18

मुझे प्रत्यक्ष क्षेत्र निर्भरता इंजेक्शन में रूचि है। परंपरागत रूप से, वसंत कन्स्ट्रक्टर इंजेक्शन (कन्स्ट्रक्टर को तर्क प्रदान करने) और सेटटर-आधारित इंजेक्शन (कॉल पर कॉलिंग सेटर्स) दोनों का समर्थन करता है।क्यों वसंत प्रत्यक्ष क्षेत्र निर्भरता इंजेक्शन का समर्थन नहीं करता है (ऑटोवॉयर को छोड़कर)?

हालांकि, वसंत @Autowired के साथ एनोटेटिंग फ़ील्ड द्वारा प्रमाणित प्रत्यक्ष क्षेत्र इंजेक्शन (एक सेटर विधि के बिना किसी ऑब्जेक्ट के सदस्य फ़ील्ड को सेट करने) में भी सक्षम है। Autowiring केवल "सेम" तक सीमित है, इसलिए आदिम मूल्यों को इंजेक्शन नहीं दिया जा सकता है (हालांकि यह वर्ग "बीवा.लांग.स्ट्रिंग" वर्ग के बीन्स बनाकर कुछ हद तक बाधित किया जा सकता है - यह काम करता है, लेकिन ऑटोवॉयरिंग की सामान्य चेतावनी है।) इसके अतिरिक्त यह, स्प्रिंग @Value का समर्थन करता है ताकि संपत्तियों से सदस्य फ़ील्ड में सीधे मूल्यों को सेट किया जा सके।

फिर भी, वसंत गुणों को सीधे सदस्य क्षेत्रों (ऑटोवॉयरिंग के बिना) पर सेट करने की अनुमति नहीं देता है।

मेरा प्रश्न है: क्यों?

यह स्पष्ट रूप से ऐसा करने में सक्षम है, तो ऐसा क्यों नहीं है? क्या कोई बड़ा नकारात्मक दुष्प्रभाव है जो इसे रोकता है? या क्या क्षमता किसी भी तरह सीमित है ताकि केवल ऑटोवॉयरिंग समझ में आती है? क्या सेटर्स को कॉल करने की तुलना में इसे कुछ बड़े हैक्स की आवश्यकता है?

ध्यान दें कि मैं सामान्य रूप से सेटर्स और गेटर्स रखने के सापेक्ष गुणों पर चर्चा नहीं करना चाहता हूं, बस कारणों से वसंत ने यह विकल्प क्यों बनाया है।

+1

मैंने हमेशा एक ही चीजों को सोचा है और माना है कि कारण "साफ कोड बनाना" से संबंधित था और इस मूल्य के आसपास संकलक जारी करने वाली संकलक की रोकथाम-कभी-कभी-सेट-और-आप-कोशिश कर रहे हैं -इसका इस्तेमाल करें। –

उत्तर

8

@Autowired एनोटेशन निजी फ़ील्ड को सुलभ बनाने के लिए प्रतिबिंब का उपयोग करता है (this related question देखें)। मैं तीन चीजें देख सकता हूं क्यों इसका उपयोग स्प्रिंग कॉन्फ़िगरेशन फ़ाइलों में नहीं किया जाता है।

  1. चूंकि कॉन्फ़िगरेशन बीन गुणों (गेटर्स और सेटर्स) द्वारा होता है, इसलिए आप वास्तव में नहीं बता सकते हैं - संभावित स्थिति में दोनों मौजूद हैं - यदि आप उदा। कॉल सेट करें या सदस्य मान सेट करें।
  2. यह encapsulation तोड़ता है। आपकी स्प्रिंग कॉन्फ़िगरेशन के पास निजी सदस्य चर के बारे में जानने का कोई कारण नहीं है। एक एनोटेशन के साथ यह ठीक है क्योंकि यह स्रोत कोड में पहले से ही सही है।
  3. सुरक्षा चिंताओं। एक अधिक प्रतिबंधक सुरक्षा प्रबंधक निजी क्षेत्रों को प्रतिबिंब के माध्यम से सुलभ बनाने की अनुमति नहीं दे सकता है।
+0

मामले 1 के लिए, मैं कहूंगा कि सेटर को पसंद करना मुश्किल है और केवल सेटर मौजूद नहीं होने पर ही फ़ील्ड की तलाश करें। मामले 2 के लिए, मुझे बिंदु नहीं दिखता है अगर वसंत को निजी सेटर्स को कॉल करने की अनुमति है। यदि वसंत निजी सेटर्स को कॉल नहीं कर सकता है, तो मुझे नहीं पता कि सदस्य चर के लिए समान पहुंच प्रतिबंध क्यों लागू नहीं किए जा सकते थे। और, मैं एक एनोटेशन के साथ भी ठीक हूं - बस ऑटोवॉयर नहीं। 3 मामले के लिए, एक अधिक प्रतिबंधक सुरक्षा प्रबंधक निजी सेटर्स को प्रतिबिंब के माध्यम से सुलभ बनाने की अनुमति नहीं दे सकता है? मुझे नहीं पता कि एक्सेस प्रतिबंध क्यों अलग होना चाहिए। – Nakedible

+0

निजी सेटर इंजेक्शन या तो एक अच्छा विचार नहीं है। मैं बिंदु 2 पर जोर देता हूं: यदि मैं निजी सदस्यों या विधियों तक पहुंचता हूं, इससे कोई फर्क नहीं पड़ता कि यह अभी भी encapsulation तोड़ता है और ओओपी और निर्भरता इंजेक्शन दोनों के सिद्धांतों के खिलाफ चला जाता है। अभी भी वही सुरक्षा मुद्दे होंगे। – Daff

+3

यदि सेटटर विधि * सार्वजनिक * है, तो सदस्य फ़ील्ड को * सार्वजनिक * क्यों नहीं होना चाहिए? या, यदि सेटटर * निजी * है, तो * निजी * सदस्य फ़ील्ड को सेट करने से कोई और सुरक्षा प्रभाव पड़ता है? – Nakedible

10

मुझे लगता है कि मुझे जवाब मिल गया है। मैं स्प्रिंग सोर्स कोड पर गया और देखा कि वास्तव में सुविधाओं को कैसे लागू किया गया था। यही वह है जो मैंने पाया:

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

सभी @Autowired आदि सामग्री को बीनपोस्टप्रोसेसर में कार्यान्वित किया गया है, जिसमें इसका स्वयं का मिलान मैकेनिक है, जिसका प्रकार रूपांतरण के साथ कुछ लेना देना नहीं है। यही कारण है कि यह केवल बीन्स इंजेक्ट करता है। @ वैल्यू के लिए वही बात बहुत अधिक है, यह केवल कुछ ऐसा है जो वहां जगह पर हल हो गया है और संपत्तियों के साथ कुछ लेना देना नहीं है।

तो, विशेष रूप से गुणों के लिए फ़ील्ड इंजेक्शन समर्थन जोड़ना, एक छोटा इंजीनियरिंग प्रयास नहीं है क्योंकि कोड के कुछ हिस्सों में एक या दूसरे बहुत अलग हैं।

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

1

यह करता (स्प्रिंग 3.0+ में)

JSR-250 @Resource एनोटेशन के माध्यम से इस समर्थन

मैं इसे व्यक्तिगत रूप से सेटर इंजेक्शन के लिए पसंद करता हूं, और कन्स्ट्रक्टर इंजेक्शन पर विचार करते समय इसके साथ मिश्रित भावनाएं होती हैं। यहां विचारों के बारे में मैंने सोचा है कि मैंने FWIW:

1) कन्स्ट्रक्टर इंजेक्शन आपके बीन निर्भरताओं (प्रो) को स्वयं-दस्तावेज़ करने का एक अच्छा तरीका है, लेकिन बहुत सारे DRY उल्लंघनों का निर्माण करता है: (ए) निजी क्षेत्र, (बी) कन्स्ट्रक्टर तर्क, (सी) सेट करने के लिए कन्स्ट्रक्टर कोड पैरामीटर से फ़ील्ड, (डी) बीन कॉन्फ़िगरेशन में अतिरिक्त कोड (या तो @ कॉन्फ़िगरेशन कक्षाओं में या xml में)। यह कुछ encapsulation शुद्धता के लिए सिर्फ DRY उल्लंघन का एक बहुत है, जिसकी मुझे परवाह नहीं है। यह मुश्किल से कैप्सूलीकरण का उल्लंघन है - लेकिन यह कुछ इंजेक्शन कंटेनर का सम्मान करता है कि JSR-250 एनोटेशन (अगले देखना)

2) JSR-250 अनुरूप कंटेनर पर निर्भरता बनाता पर एक बड़ी निर्भरता पैदा करता है। मेरी इस बारे में मिश्रित भावनायें है। जब मैंने पहली बार @ रिसोर्स के बारे में सुना तो मैंने इसे लिखा था कि यह मेरी प्रणाली को परीक्षण करने में कठोर बना देगा। हालांकि, मैं अपने परीक्षणों में वैसे भी वसंत का उपयोग कर समाप्त हुआ। मैं अभी भी नकली बीन्स का उपयोग कर सकता हूं जैसे कि मैं वैसे भी करता हूं, इसलिए यह वास्तव में कभी भी एक समस्या नहीं थी। और सवाल परीक्षण के बाहर है, आप वास्तव में इसका पुन: उपयोग कब करना चाहते हैं। मेरे दिमाग में यदि आप एक कंटेनर का लाभ लेने के लिए सिस्टम को डिजाइन कर रहे हैं, तो इसे गले लगाओ और इसका इस्तेमाल करें। सूखे उल्लंघन वास्तव में एक कंटेनर के अंदर नहीं चलने की लचीलापन के लायक हैं? कम से कम जेएसआर-250 एनोटेशन के साथ आप किसी भी जेईई 6 पर्यावरण में भाग सकते हैं और इंजेक्शन प्राप्त कर सकते हैं जैसे आप चाहते हैं।

3) यदि आप कंटेनर के बाहर एक को तुरंत चालू करते हैं तो कुछ बहुत अच्छे डिबगिंग परिदृश्य नहीं बना सकते हैं: यानी आपको कुछ अच्छे के बजाय शून्य सूचक अपवाद प्राप्त होंगे। यह एक व्यापार बंद है। मैं व्यक्तिगत रूप से सोचता हूं कि यह भयानक नहीं है - मेरा मतलब है कि अगर आपको @Resource के साथ एक पंक्ति पर एनपीई मिलता है तो आपको जल्दी से एहसास होता है कि इसे इंजेक्शन नहीं दिया गया था।

+0

@ संसाधन एनोटेशन नाम से स्वायत्त हैं, जो मैं नहीं ढूंढ रहा था। – Nakedible

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