स्प्रिंग फ्रेमवर्क में डिपेंडेंसी इंजेक्शन और नियंत्रण का व्युत्क्रम क्या है?


111

"निर्भरता इंजेक्शन" और "नियंत्रण का व्युत्क्रम" अक्सर वेब फ्रेमवर्क विकसित करने के लिए स्प्रिंग फ्रेमवर्क का उपयोग करने के प्राथमिक लाभों के रूप में उल्लेख किया जाता है

क्या कोई समझा सकता है कि यदि संभव हो तो उदाहरण के साथ यह बहुत ही सरल शब्दों में है?



3
@SteveChambers इसकी डुप्लिकेट नहीं है, यह सवाल स्प्रिंग्स पर्सपेक्टिव में पूछा जाता है। यह प्रश्न सामान्य रूप से निर्धारित है।
VdeX

जवाबों:


233
  • वसंत निर्भरता इंजेक्शन के कारण शिथिल युग्मित अनुप्रयोगों के निर्माण में मदद करता है ।
  • वसंत में, वस्तुएं अपने संघों (निर्भरता) को परिभाषित करती हैं और इस बात की चिंता नहीं करती हैं कि वे उन निर्भरताओं को कैसे प्राप्त करेंगे । वस्तुओं को बनाने के लिए आवश्यक निर्भरता प्रदान करना वसंत की जिम्मेदारी है।

उदाहरण के लिए : मान लीजिए कि हमारे पास एक वस्तु है Employeeऔर इसकी वस्तु पर निर्भरता है Address। हम एक सेम को Employeeउसी के अनुसार परिभाषित करेंगे जो वस्तु पर उसकी निर्भरता को परिभाषित करेगा Address

जब वसंत एक Employeeवस्तु बनाने की कोशिश करता है , तो वह देखेगा कि उस Employeeपर निर्भरता है Address, इसलिए वह पहले Addressवस्तु (आश्रित वस्तु) का निर्माण करेगा और फिर उसे Employeeवस्तु में इंजेक्ट करेगा ।

  • नियंत्रण का उलटा ( IoC ) और निर्भरता इंजेक्शन ( DI ) का उपयोग परस्पर विनिमय के लिए किया जाता है। IoC DI के माध्यम से प्राप्त किया जाता है। DI निर्भरता प्रदान करने की प्रक्रिया है और IoC DI का अंतिम परिणाम है। ( नोट: DI IoC को प्राप्त करने का एकमात्र तरीका नहीं है। अन्य तरीके भी हैं।)

  • डीआई द्वारा, वस्तुओं को बनाने की जिम्मेदारी हमारे आवेदन कोड से स्प्रिंग कंटेनर में स्थानांतरित कर दी गई है; इस घटना को IoC कहा जाता है।

  • डिपेंडेंसी इंजेक्शन सेटर इंजेक्शन या कंस्ट्रक्टर इंजेक्शन द्वारा किया जा सकता है।

मैं असहमत हूं। मुझे नहीं लगता कि यह एक स्पष्ट व्याख्या है। आप इसे क्रेट करने और इसे इंजेक्ट करने के लिए एक रूपरेखा प्राप्त करने के बजाय "कर्मचारी" के अंदर "पता" को तुरंत क्यों नहीं लिख सकते? थोड़ा और विस्तृत उदाहरण के लिए कहा जाता है।
बोरिस

2
@ बोरिस ने कहा कि आप अपनी खुद की वस्तुओं को नहीं रोक सकते। लेकिन उत्तर का एकमात्र उद्देश्य यह प्रदर्शित करना था कि आप डीआई के साथ कैसे प्राप्त कर सकते हैं। आपके पास क्लाइंट कोड द्वारा DI और ऑब्जेक्ट दोनों को तत्काल किया जा सकता है। इसे अभी भी IOC कहा जाएगा, कम से कम आंशिक रूप से।
bogdan.rusu


बोरिस। ज़्यादा ईर्ष्यालु? यह सबसे अच्छा जवाब है।
अनिकेत कापसे

31

मैं इस दो शब्दों के बारे में अपनी सरल समझ लिखूंगा: (त्वरित समझ के लिए सिर्फ उदाहरण पढ़ें)

  • निर्भरता इंजेक्शन (DI):
    डिपेंडेंसी इंजेक्शन का मतलब आम तौर पर एक आश्रित वस्तु को एक विधि के पैरामीटर के रूप में पारित करना है, बजाय इसके कि विधि निर्भर वस्तु का निर्माण करे
    व्यवहार में इसका क्या अर्थ है कि विधि का किसी विशेष कार्यान्वयन पर प्रत्यक्ष निर्भरता नहीं है; आवश्यकताओं को पूरा करने वाले किसी भी कार्यान्वयन को एक पैरामीटर के रूप में पारित किया जा सकता है।

    इसके साथ वस्तुओं का कार्यान्वयन उनकी निर्भरता को परिभाषित करता है। और वसंत इसे उपलब्ध करता है।
    यह शिथिल युग्मित अनुप्रयोग विकास की ओर ले जाता है।

    त्वरित उदाहरण: एम्प्लीयली ऑबजेक्टेन को बनाया गया है, यह स्वचालित रूप से तैयार होगा (यदि पता कर्मचारी वस्तु द्वारा निर्भरता के रूप में परिभाषित किया गया है) *।

  • नियंत्रण का उलटा (IoC) कंटेनर:
    यह चौखटे की सामान्य विशेषता है, IoC जावा वस्तुओं का प्रबंधन करता है
    - इसके बीनफैक्ट्री के माध्यम से तात्कालिकता से विनाश तक।
    - आईओसी कंटेनर द्वारा इंस्टेंट किए गए जावा घटकों को बीन्स कहा जाता है, और आईओसी कंटेनर बीन के दायरे, जीवनचक्र की घटनाओं और किसी भी एओपी सुविधाओं का प्रबंधन करता है जिसके लिए इसे कॉन्फ़िगर और कोडित किया गया है।

    QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it

    नियंत्रण के उलटा लागू करने से, एक सॉफ्टवेयर / वस्तु उपभोक्ता को नियंत्रित या कम विकल्प होने के बजाय सॉफ्टवेयर / वस्तुओं पर अधिक नियंत्रण / विकल्प मिलते हैं।

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

मैं यहां चीजों को सार रखूंगा, आप विषय की विस्तार से समझ के लिए निम्नलिखित लिंक पर जा सकते हैं।

उदाहरण के साथ एक अच्छा पढ़ा

विस्तृत विवरण


11

स्प्रिंग ऑब्जेक्ट में शिथिल रूप से युग्मित किया जाता है अर्थात, प्रत्येक वर्ग एक दूसरे से स्वतंत्र होता है ताकि सब कुछ व्यक्तिगत रूप से परखा जा सके। लेकिन उन कक्षाओं का उपयोग करते समय, एक वर्ग अन्य वर्गों पर निर्भर हो सकता है, जिन्हें पहले तत्काल करने की आवश्यकता होती है।

तो, हम वसंत को बताते हैं कि क्लास ए क्लास बी पर निर्भर है। इसलिए क्लास ए के लिए बीन (क्लास की तरह) बनाते समय, क्लास बी को क्लास ए से पहले इंस्टेंटेट करता है और इंजेक्ट करता है कि क्लास ए में सेटर या कंस्ट्रक्टर डीआई विधियों का उपयोग किया जाए। यानी, हम वसंत को रन-टाइम पर निर्भरता बता रहे हैं। यह डीआई है।

जैसा कि, हम ऑब्जेक्ट्स (सेम) बनाने की ज़िम्मेदारी सौंप रहे हैं, उन्हें और उनके एकत्रीकरण को हार्ड-कोडिंग के बजाय स्प्रिंग पर बनाए रखना है, हम इसे इन्वर्ट ऑफ कंट्रोल (IOC) कहते हैं।


7

नियंत्रण का उलटा (IOC):

IoC एक डिज़ाइन पैटर्न है जो किसी सिस्टम में नियंत्रण के प्रवाह को बदलने का वर्णन करता है, इसलिए निष्पादन प्रवाह कोड के एक केंद्रीय टुकड़े द्वारा नियंत्रित नहीं किया जाता है। इसका मतलब यह है कि घटकों को केवल अन्य घटकों के सार पर निर्भर होना चाहिए और निर्भर वस्तुओं के निर्माण को संभालने के लिए जिम्मेदार नहीं हैं। इसके बजाय, ऑब्जेक्ट इंस्टेंसेस को डिपेंडेंसी इंजेक्शन (DI) के माध्यम से एक IoC कंटेनर द्वारा रनटाइम पर आपूर्ति की जाती है।

आईओसी बेहतर सॉफ्टवेयर डिज़ाइन को सक्षम करता है जो पुन: उपयोग, ढीली युग्मन और सॉफ्टवेयर घटकों के आसान परीक्षण की सुविधा प्रदान करता है।

निर्भरता इंजेक्शन (DI):

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

और देखने के लिए क्लिक करें


6

स्प्रिंग: स्प्रिंग जावा प्लेटफॉर्म के लिए "इन्वर्ज़न ऑफ कंट्रोल" कंटेनर है।

कंट्रोल ऑफ इन्वर्ट (IoC): इन्वर्ट ऑफ कंट्रोल (IoC) एक ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग प्रैक्टिस है, जिसके तहत ऑब्जेक्ट युग्मन को "असेंबलर" ऑब्जेक्ट द्वारा रनटाइम पर बांधा जाता है और आमतौर पर स्थैतिक विश्लेषण का उपयोग करके संकलन समय पर पता नहीं चलता है।

डिपेंडेंसी इंजेक्शन (DI): "डिपेंडेंसी इंजेक्शन एक सॉफ्टवेयर डिज़ाइन पैटर्न है जो हार्ड-कोडेड निर्भरता को हटाने की अनुमति देता है और यह उन्हें बदलना संभव बनाता है, चाहे रन-टाइम या संकलन-समय पर।" -wiki।


यह जो पहले से ही बाहर है (जो कि यह उत्तर कहां से खट्टा है) की तुलना में यह कितना सरल है? यह ओपी के अनुरोध को सरलता के लिए नहीं बताता है, जब तक कि शब्दावली के आसपास दोहरे उद्धरण जादुई तरीके से चीजों को सरल नहीं बनाते हैं।
udun

6

नियंत्रण का विलोम- इसका अर्थ है कि स्प्रिंग बीओसी को स्प्रिंग आईओसी कंटेनर में बनाने और उसे तुरंत देने का नियंत्रण और डेवलपर द्वारा किया जाने वाला एकमात्र कार्य स्प्रिंग एक्सएमएल फ़ाइल में सेम को कॉन्फ़िगर करना है।

निर्भरता अन्तःक्षेपण-

एक वर्ग कर्मचारी पर विचार करें

class Employee { 
   private int id;
   private String name;
   private Address address;

   Employee() {
     id = 10;
     name="name";
     address = new Address();
   }


}

और कक्षा के पते पर विचार करें

class Address {
   private String street;
   private String city;

   Address() {
     street="test";
     city="test1";

  }
}

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

  1. सेटर इंजेक्शन

कर्मचारी वर्ग में सेटर विधि जो एड्रेस क्लास का संदर्भ लेती है

public void setAddress(Address addr) {
    this.address = addr;
}
  1. कंस्ट्रक्टर इंजेक्शन

कर्मचारी वर्ग में कंस्ट्रक्टर जो पते को स्वीकार करता है

Employee(Address addr) {
      this.address = addr;
}

इस तरह से पता वर्ग मानों को स्वतंत्र रूप से सेटर / कंस्ट्रक्टर इंजेक्शन का उपयोग करके सेट किया जा सकता है।


3

नियंत्रण का उलटना सॉफ्टवेयर आर्किटेक्चर का एक सामान्य डिजाइन सिद्धांत है जो पुन: प्रयोज्य, मॉड्यूलर सॉफ्टवेयर फ्रेमवर्क बनाने में सहायता करता है जिन्हें बनाए रखना आसान है।

यह एक डिजाइन सिद्धांत है जिसमें सामान्य लिखित पुस्तकालय या पुन: प्रयोज्य कोड से नियंत्रण का प्रवाह "प्राप्त" होता है।

इसे बेहतर ढंग से समझने के लिए, हम देखते हैं कि कोडिंग के पहले के दिनों में हम कैसे कोड करते थे। प्रक्रियात्मक / पारंपरिक भाषाओं में, व्यावसायिक तर्क आम तौर पर अनुप्रयोग के प्रवाह को नियंत्रित करता है और सामान्य या पुन: प्रयोज्य कोड / फ़ंक्शन को "कॉल" करता है। उदाहरण के लिए, एक साधारण कंसोल एप्लिकेशन में, मेरे प्रोग्राम के निर्देशों द्वारा मेरा नियंत्रण नियंत्रित किया जाता है, जिसमें कुछ सामान्य पुन: प्रयोज्य कार्यों के लिए कॉल शामिल हो सकते हैं।

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

आईओआरसी के साथ कंट्रास्ट में, फ्रेमवर्क पुन: प्रयोज्य कोड है जो व्यापार तर्क को "कॉल" करता है।

उदाहरण के लिए, एक विंडोज़ आधारित प्रणाली में, पहले से ही यूआई तत्वों जैसे बटन, मेनू, विंडोज़ और डायलॉग बॉक्स बनाने के लिए एक रूपरेखा उपलब्ध होगी। जब मैं अपने आवेदन का व्यावसायिक तर्क लिखता हूं, तो यह फ्रेमवर्क की घटनाएं होंगी जो मेरे व्यवसाय तर्क कोड (जब किसी घटना को निकाल दिया जाता है) को कॉल करेंगी और इसके विपरीत नहीं।

हालाँकि, फ्रेमवर्क कोड को मेरे व्यावसायिक तर्क के बारे में पता नहीं है, फिर भी यह पता चलेगा कि मेरे कोड को कैसे कॉल किया जाए। यह ईवेंट्स / डेलीगेट्स, कॉलबैक आदि का उपयोग करके हासिल किया जाता है। यहाँ प्रवाह का नियंत्रण "उलटा" है।

इसलिए, सांख्यिकीय रूप से बाध्य वस्तुओं पर नियंत्रण के प्रवाह के आधार पर, प्रवाह समग्र वस्तु ग्राफ और विभिन्न वस्तुओं के बीच संबंधों पर निर्भर करता है।

डिपेंडेंसी इंजेक्शन एक डिज़ाइन पैटर्न है जो वस्तुओं की निर्भरता को हल करने के लिए IoC सिद्धांत को लागू करता है।

सरल शब्दों में, जब आप कोड लिखने की कोशिश कर रहे हैं, तो आप विभिन्न कक्षाओं का निर्माण और उपयोग कर रहे होंगे। एक वर्ग (क्लास ए) अन्य कक्षाओं (कक्षा बी और / या डी) का उपयोग कर सकता है। तो, क्लास बी और डी क्लास ए की निर्भरता हैं।

एक साधारण सादृश्य एक क्लास कार होगी। एक कार इंजन, टायर और अन्य जैसे अन्य वर्गों पर निर्भर हो सकती है।

डिपेंडेंसी इंजेक्शन बताता है कि डिपेंडेंट क्लासेस (क्लास कार) के बजाय अपनी निर्भरता (क्लास इंजन और क्लास टायर) बनाने के लिए, क्लास को डिपेंडेंसी के ठोस उदाहरण के साथ इंजेक्ट किया जाना चाहिए।

अधिक व्यावहारिक उदाहरण से समझें। विचार करें कि आप अपना खुद का TextEditor लिख रहे हैं। अन्य बातों के अलावा, आपके पास एक स्पेलकचर हो सकता है जो उपयोगकर्ता को अपने पाठ में टाइपोस की जांच करने की सुविधा प्रदान करता है। इस तरह के एक कोड का एक सरल कार्यान्वयन हो सकता है:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

पहली नजर में सब रौबदार लगता है। उपयोगकर्ता कुछ पाठ लिखेगा। डेवलपर टेक्स्ट को कैप्चर करेगा और CheckSpellings फ़ंक्शन को कॉल करेगा और टाइपोस की एक सूची ढूंढेगा जिसे वह उपयोगकर्ता को दिखाएगा।

सब कुछ एक महान दिन तक काम करने लगता है जब एक उपयोगकर्ता संपादक में फ्रेंच लिखना शुरू करता है।

अधिक भाषाओं के लिए सहायता प्रदान करने के लिए, हमारे पास अधिक वर्तनी जाँचक होने की आवश्यकता है। संभवतः फ्रेंच, जर्मन, स्पेनिश आदि।

यहां, हमने "अंग्रेज़ी" स्पेलचैकर के साथ एक कसकर-युग्मित कोड बनाया है, जो हमारे TextEditor वर्ग के साथ कसकर युग्मित किया जा रहा है, जिसका अर्थ है कि हमारा TextEditor वर्ग EnglishSpellChecker पर निर्भर है या अन्य अंग्रेजी में SpellCheker TextEditor के लिए निर्भरता है। हमें इस निर्भरता को दूर करने की आवश्यकता है। इसके अलावा, हमारे पाठ संपादक को रन टाइम में डेवलपर के विवेक के आधार पर किसी भी वर्तनी परीक्षक के ठोस संदर्भ को रखने का एक तरीका चाहिए।

इसलिए, जैसा कि हमने DI के परिचय में देखा, यह सुझाव देता है कि वर्ग को अपनी निर्भरता के साथ इंजेक्ट किया जाना चाहिए। इसलिए, कॉलिंग कोड की जिम्मेदारी होनी चाहिए कि वह सभी निर्भरता को वर्ग / कोड को इंजेक्ट करे। इसलिए हम अपने कोड का पुनर्गठन कर सकते हैं

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

हमारे उदाहरण में, TextEditor वर्ग को ISpellChecker प्रकार का ठोस उदाहरण प्राप्त करना चाहिए।

अब, निर्भरता को कंस्ट्रक्टर, एक सार्वजनिक संपत्ति या एक विधि में इंजेक्ट किया जा सकता है।

कंस्ट्रक्टर डीआई का उपयोग करके हमारी कक्षा को बदलने की कोशिश करें। परिवर्तित TextEditor वर्ग कुछ इस तरह दिखाई देगा:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

ताकि टेक्स्ट एडिटर बनाते समय कॉलिंग कोड, टेक्स्ट एडिटर के उदाहरण के लिए उपयुक्त SpellChecker प्रकार को इंजेक्ट कर सके।

पूरा लेख आप यहां पढ़ सकते हैं


1

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

तो वसंत में हम बस वसंत कंटेनर पर निर्भर करते हैं जो हमें निर्भरता वस्तु प्रदान करते हैं।


1

IOC वह तकनीक है जहां आप किसी और को आपके लिए ऑब्जेक्ट बनाने देते हैं। और वसंत के मामले में कोई और IOC कंटेनर है।

डिपेंडेंसी इंजेक्शन एक ऐसी तकनीक है जिसमें एक वस्तु किसी अन्य वस्तु की निर्भरता की आपूर्ति करती है।

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