2010-06-30 14 views
388

मैं थोड़ा उलझन में हूं कि कैसे inversion of control (IoC) Spring में काम करता है।स्प्रिंग में ऑटोवॉयरिंग कैसे काम करता है?

कहें कि मेरे पास UserServiceImpl नामक एक सेवा वर्ग है जो UserService इंटरफ़ेस लागू करता है।

यह @Autowired कैसे होगा?

और मेरे Controllers कार्रवाई में, मैं इस सेवा का एक instance कैसे instantiate हैं?

क्या मैं निम्नलिखित करूँगा?

UserService userService = new UserServiceImpl(); 
+0

[समझना स्प्रिंग @Autowired उपयोग] (https की संभावित डुप्लिकेट से मिल गया।कॉम/प्रश्न/1 9 414734/समझ-वसंत-ऑटोवायर-उपयोग) – tkruse

उत्तर

570

पहला, और सबसे महत्वपूर्ण - सभी वसंत बीन्स प्रबंधित होते हैं - वे "अनुप्रयोग संदर्भ" नामक एक कंटेनर के अंदर "रहते हैं"।

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

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

एप्लिकेशन संदर्भ में "जीवित" क्या है? इसका मतलब है कि संदर्भ वस्तुओं को तुरंत चालू करता है, न कि आप। अर्थात। - आप कभी भी new UserServiceImpl() नहीं बनाते - कंटेनर प्रत्येक इंजेक्शन बिंदु पाता है और वहां एक उदाहरण सेट करता है।

@Controller // Defines that this class is a spring bean 
@RequestMapping("/users") 
public class SomeController { 

    // Tells the application context to inject an instance of UserService here 
    @Autowired 
    private UserService userService; 

    @RequestMapping("/login") 
    public void login(@RequestParam("username") String username, 
      @RequestParam("password") String password) { 

     // The UserServiceImpl is already injected and you can use it 
     userService.login(username, password); 

    } 
} 

कुछ नोट::

अपने नियंत्रकों में, आप बस निम्न होना

  • में अपने applicationContext.xml आप <context:component-scan> ताकि कक्षाएं @Controller, @Service के लिए स्कैन किए सक्षम होना चाहिए, आदि एनोटेशन।
  • स्प्रिंग-एमवीसी अनुप्रयोग के लिए प्रवेश बिंदु डिस्पैचर सर्वलेट है, लेकिन यह आपके से छिपा हुआ है, और इसलिए दृश्य संदर्भ के प्रत्यक्ष संपर्क और बूटस्ट्रैपिंग दृश्य के पीछे होती है।
  • UserServiceImpl को बीन के रूप में भी परिभाषित किया जाना चाहिए - या तो <bean id=".." class=".."> का उपयोग करके या @Service एनोटेशन का उपयोग करना। चूंकि यह UserService का एकमात्र कार्यान्वयन होगा, इसे इंजेक्शन दिया जाएगा।
  • @Autowired एनोटेशन के अलावा, वसंत एक्सएमएल-कॉन्फ़िगर करने योग्य ऑटोवॉयरिंग का उपयोग कर सकता है। उस स्थिति में जिन क्षेत्रों में नाम या प्रकार होता है जो किसी मौजूदा बीन से मेल खाते हैं, स्वचालित रूप से एक बीन इंजेक्शन प्राप्त करते हैं। वास्तव में, यह ऑटोवॉयरिंग का प्रारंभिक विचार था - किसी भी कॉन्फ़िगरेशन के बिना निर्भरताओं के साथ इंजेक्शन वाले फ़ील्ड रखने के लिए। अन्य टिप्पणियां जैसे @Inject, @Resource का भी उपयोग किया जा सकता है।
+0

आपका अंतिम बिंदु, इसलिए इंटरफ़ेस के प्रत्यारोपण में, UserServiceImpl, मैं @Service के साथ एनोटेट सही करता हूं? महान जवाब, वास्तव में मेरे लिए चीजों को मंजूरी दे दी। – Blankman

+0

उपयोगकर्ता सेवा उपयोगकर्ता इंटरफ़ेस सेवा है? – Blankman

+6

हाँ, UserServiceImpl को सेवा के साथ एनोटेट किया गया है, और उपयोगकर्ता सेवा इंटरफ़ेस – Bozho

57

इस पर निर्भर करता है कि क्या आप एनोटेशन रूट या बीन एक्सएमएल परिभाषा मार्ग गए हैं या नहीं।

कहो आप सेम अपने applicationContext.xml में परिभाषित किया गया था:

<beans ...> 

    <bean id="userService" class="com.foo.UserServiceImpl"/> 

    <bean id="fooController" class="com.foo.FooController"/> 

</beans> 

autowiring होता है जब आवेदन शुरू होता है। तो, fooController, जो तर्क के लिए खातिर UserServiceImpl वर्ग का उपयोग करना चाहता है, तो आप इसे इस रूप में व्याख्या चाहते हैं:

public class FooController { 

    // You could also annotate the setUserService method instead of this 
    @Autowired 
    private UserService userService; 

    // rest of class goes here 
} 

यह देखता है @Autowired, स्प्रिंग एक वर्ग है कि applicationContext में संपत्ति से मेल खाता है के लिए दिखाई देगा, और इसे स्वचालित रूप से इंजेक्ट करें। यदि आपके पास 1 से अधिक उपयोगकर्ता सेवा बीन हैं, तो आपको यह समझना होगा कि इसका उपयोग किसके लिए करना चाहिए।

आप निम्नलिखित करते हैं:

UserService service = new UserServiceImpl(); 

यह @Autowired लेने नहीं होगा जब तक आप इसे अपने आप को निर्धारित किया है।

+1

तो 'applicationContext.xml' में' बीन आईडी 'को परिभाषित करने का क्या उपयोग है। हमें 'userService' चर के साथ' userService' चर परिभाषित करना होगा। तो 'xml' फ़ाइल में प्रवेश क्यों करें। – viper

16

@Autowired एक एनोटेशन स्प्रिंग 2.5 में शुरू की गई है, और यह केवल इंजेक्शन के लिए प्रयोग किया जाता है। उदाहरण के लिए:

class A { 

    private int id; 

    // With setter and getter method 
} 

class B { 

    private String name; 

    @Autowired // Here we are injecting instance of Class A into class B so that you can use 'a' for accessing A's instance variables and methods. 
    A a; 

    private int roll; 

    // With setter and getter method 

    public void showDetail() { 
     System.out.println("Value of id form A class" + a.getId();); 
    } 
} 
+5

यह संकलित नहीं होगा और आमतौर पर गलत है। 'Autowired' का अर्थ यह नहीं है कि" आप कक्षा 'ए'' से 'बी' कक्षा में सभी फ़ंक्शन (विधि) और चर का उपयोग कर सकते हैं। यह क्या करता है 'बी' के उदाहरणों में 'ए' का उदाहरण लाता है, ताकि आप 'बी 'से' a.getId() 'कर सकें। –

+0

@dimadima तो अगर वह System.out.println ("आईडी फॉर्म ए क्लास का मूल्य" + a.getId()) ;, और जैसा कि उसने वास्तव में किया है, उतना ही सही नहीं होगा। कृपया उत्तर दें, क्योंकि यह मेरे लिए सहजता से स्पष्ट है और मेरे वर्तमान स्तर की समझ के अनुसार ऑटोवॉयरिंग समझा रहा है। –

+0

स्वायत्त एनोटेशन वसंत 2.5 में पेश किया गया है http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/beans/factory/annotation/Autowired.html – SpringLearner

6

@Autowired

  • एक निर्माता, क्षेत्र, सेटर विधि या config पद्धति के रूप में स्प्रिंग की निर्भरता इंजेक्शन सुविधाओं से autowired होने के लिए चिह्नित करता है।

  • केवल एक किसी भी सेम वर्ग के निर्माता (अधिकतम) इस एनोटेशन ले सकते हैं, निर्माता जब एक वसंत सेम के रूप में इस्तेमाल करने के लिए autowire का संकेत है। ऐसे कन्स्ट्रक्टर को सार्वजनिक होना जरूरी नहीं है।

  • किसी भी कॉन्फ़िगरेशन विधियों को लागू करने से पहले फ़ील्ड को बीन के निर्माण के ठीक बाद इंजेक्शन दिया जाता है। इस तरह की एक config क्षेत्र सार्वजनिक होने के लिए नहीं है।

  • कॉन्फ़िगरेशन विधियों का मनमाना नाम हो सकता है और तर्कों की संख्या हो सकती है; उन तर्कों में से प्रत्येक वसंत कंटेनर में मेल खाने वाले सेम के साथ autowired कर दिया जाएगा। बीन संपत्ति सेटर तरीकों प्रभावी रूप से सिर्फ इस तरह के एक सामान्य config विधि का एक विशेष मामला है। इस तरह के config तरीकों सार्वजनिक होने के लिए नहीं है।

  • एकाधिक तर्क विधियों के मामले में, 'आवश्यक' पैरामीटर सभी तर्कों के लिए लागू है।

  • संग्रह या मानचित्र निर्भरता प्रकार के मामले में, कंटेनर घोषित मूल्य प्रकार से मेल खाने वाले सभी बीन्स स्वचालित रूप से करेगा। एक मानचित्र के मामले में, कुंजी प्रकार स्ट्रिंग के रूप में घोषित किया जाना चाहिए और इसी सेम नामों को सुलझा लिया जाएगा।

3

तुम बस

@Service("userService") 

स्प्रिंग कंटेनर इस वर्ग के जीवन चक्र की देखभाल के रूप में यह सेवा के रूप में दर्ज किए जाएंगे टिप्पणी के साथ आपकी सेवा वर्ग UserServiceImpl टिप्पणी करने की जरूरत है।

फिर अपने नियंत्रक में आप ऑटो वायर (तत्काल) कर सकते हैं और इसकी कार्यक्षमता का उपयोग कर सकते हैं।

@Autowired 
UserService userService; 
6

@Autowired आंतरिक रूप से कैसे काम करता है?

पूर्व - अगर @Autowired

<bean id="englishGreeting" class="com.bean.EnglishGreeting"> 
    <property name="greeting" ref="greeting"/> 
</bean> 

<bean id="greeting" class="com.bean.Greeting"> 
    <property name="message" value="Hello World"/> 
</bean> 

का उपयोग नहीं कर आप @Autowired उपयोग कर रहे हैं तो

class EnglishGreeting { 
    @Autowired //so automatically based on the name it will identify the bean and inject. 
    private Greeting greeting; 
    //setter and getter 
} 

.xml फ़ाइल

class EnglishGreeting { 
    private Greeting greeting; 
    //setter and getter 
} 

class Greeting { 
    private String message; 
    //setter and getter 
} 

फ़ाइल .xml यह एक जैसे दिखते हैं @Autowired

का उपयोग न करने पर समान रूप से दिखाई देगा
<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean> 

<bean id="greeting" class="com.bean.Greeting"> 
    <property name="message" value="Hello World"/> 
</bean> 

अभी भी कुछ संदेह है तो लाइव डेमो नीचे के माध्यम से जाने

How does @Autowired work internally ?

+0

बस बिल्कुल सही। – srk

0

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

1

वसंत निर्भरता इंजेक्शन आपको अपनी कक्षाओं से युग्मन हटाने में मदद करता है। इसके बजाय इस

UserService userService = new UserServiceImpl(); 

की तरह वस्तु बनाने के लिए आप इस को प्राप्त करने के लिए डि

@Autowired 
private UserService userService; 

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

public class AccController { 

    @Autowired 
    private UserService userService; 
} 

आप ध्यान रखें कि आप वसंत विन्यास फाइल में तत्व <context:annotation-config/> जोड़कर @Autowired एनोटेशन सक्षम करना होगा रखें एक जावा विन्यास आधारित POC यहाँ example

0

पा सकते हैं। यह AutowiredAnotationBeanPostProcessor पंजीकृत करेगा जो एनोटेशन की प्रक्रिया का ख्याल रखता है।

और फिर आप फील्ड इंजेक्शन विधि का उपयोग कर अपनी सेवा को स्वचालित कर सकते हैं। // stackoverflow:

public class YourController{ 

@Autowired 
private UserService userService; 

} 

मैं पद Spring @autowired annotation

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