java - كيف يعمل التشغيل التلقائي في الربيع؟




spring spring-mvc (6)

أنا مرتبك قليلاً حول كيفية عمل انعكاس التحكم ( IoC ) في Spring .

قل لدي فئة خدمة تسمى UserServiceImpl بتنفيذ واجهة UserService .

كيف سيكون هذا @Autowired ؟

وفي الإجراء الخاص بـ Controllers ، كيف يمكنني instantiate instance لهذه الخدمة؟

هل سأفعل ما يلي؟

UserService userService = new UserServiceImpl();

Autowired

  • يحدد مُنشئًا أو حقلًا أو طريقة تعيين أو طريقة تهيئة حتى يتم استقراءها بواسطة مرافق حقن التبعية في الربيع.

  • يمكن لمنشئ واحد فقط (كحد أقصى) من أي فئة حبة معينة أن يحمل هذا التعليق التوضيحي ، مشيراً إلى المنشئ إلى autowire عند استخدامه كصنف Spring. مثل هذا المنشئ لا يجب أن يكون علنياً.

  • يتم حقنها الحق بعد بناء حبة ، قبل أن يتم استدعاء أي أساليب التكوين. ليس من الضروري أن يكون حقل التهيئة هذا عامًا.

  • قد يكون لطرق التكوين اسمًا عشوائيًا وأي عدد من الوسائط. كل واحدة من هذه الحجج سيتم استقراءها باستخدام حبة مطابقة في حاوية الربيع. تعتبر أساليب تعيين خصائص حبيبات الفاصوليا مجرد حالة خاصة من مثل هذه الطريقة العامة للتهيئة. لا يجب أن تكون طرق التهيئة العامة هذه.

  • في حالة استخدام وسائط متعددة ، تنطبق المعلمة "المطلوبة" على جميع الوسيطات.

  • في حالة نوع تبعية Collection أو Map ، ستقوم الحاوية تلقائيًا بتخزين جميع الفاصوليا التي تطابق نوع القيمة المصرح به. في حالة وجود خريطة ، يجب أن يتم التصريح عن المفاتيح كنوع String وسيتم حلها إلى أسماء وحدات التخزين المقابلة.


أولاً ، والأكثر أهمية - تتم إدارة جميع حبوب الربيع - فهي "تعيش" داخل حاوية تسمى "سياق التطبيق".

ثانياً ، لكل تطبيق نقطة دخول إلى هذا السياق. تطبيقات الويب تحتوي على Servlet ، يستخدم JSF محلل el ، إلخ. وهناك أيضًا مكان يتم فيه تشغيل سياق التطبيق وجميع الفاصوليا - autowired. في تطبيقات الويب هذا يمكن أن يكون مستمع بدء التشغيل.

يحدث Autowiring عن طريق وضع مثيل واحد من الفول في الحقل المطلوب في مثيل من حبة أخرى. يجب أن تكون كلتا الفئتين من الفاصوليا ، أي يجب تعريفهما للعيش في سياق التطبيق.

ما هو "العيش" في سياق التطبيق؟ هذا يعني أن سياق instantiates الكائنات ، وليس لك. أي - لن تقوم أبدًا new UserServiceImpl() الحاوية كل نقطة حقن 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 الخاص بك @Controller ، يجب تمكين <context:component-scan> بحيث يتم فحص الفصول الدراسية لـ @Controller ، @Service ، الخ التعليقات التوضيحية.
  • نقطة الإدخال الخاصة بتطبيق Spring-MVC هي DispatcherServlet ، ولكنها مخفية عنك ، وبالتالي يحدث التفاعل المباشر والتشغيل البسيط لسياق التطبيق خلف المشهد.
  • يجب أيضًا تعريف UserServiceImpl على أنه bean - إما باستخدام <bean id=".." class=".."> أو باستخدام التعليق التوضيحي لـ @Service . وبما أنه سيكون المنفذ الوحيد لـ UserService ، فسيتم حقنه.
  • بصرف النظر عن التعليق التوضيحي @Autowired ، يمكن لـ Spring استخدام autowiring القابلة للتكوين بتنسيق XML. في هذه الحالة ، تحصل جميع الحقول التي تحتوي على اسم أو نوع تتطابق مع حبة حالية تلقائيًا على وحدة حقنها. في الواقع ، كانت تلك هي الفكرة الأولية عن الاستقراء الذاتي - أن يتم حقن الحقول بموثوقية دون أي تكوين. التعليقات الأخرى مثل @Inject ، @Resource يمكن استخدامها أيضًا.

ضع في اعتبارك أنه يجب تمكين التعليق التوضيحيAoutowired عن طريق إضافة عنصر <context:annotation-config/> إلى ملف تكوين فصل الربيع. سيقوم هذا بتسجيل AutowiredAnnotationBeanPostProcessor الذي يعتني معالجة التعليق التوضيحي.

وبعد ذلك يمكنك جعل خدمة الإنترنت الخاصة بك باستخدام طريقة الحقن الميداني.

public class YourController{

 @Autowired
 private UserService userService; 

}

لقد عثرت على هذا التعليق التوضيحي التالي من Spring @ autowired


كيف يعمل @ أتواتير داخليا؟

السابق -

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

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

ملف .xml سيبدو متشابهًا إذا لم يكن يستخدم @ Inoutired

<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>

إذا كنت تستخدم @ Atowired بعد ذلك

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

ملف .xml سيبدو متشابهًا إذا لم يكن يستخدم @ Inoutired

<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>

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

إذا كان لا يزال لديك بعض الشك ثم انتقل من خلال العرض المباشر

كيف يعمل @ أتواتير داخليا؟


يساعدك الاعتماد على التبعية في الربيع على إزالة الاقتران من فصولك الدراسية. بدلا من إنشاء كائن مثل هذا

UserService userService = new UserServiceImpl();

سوف تستخدم هذا بعد إدخال DI

@Autowired
private UserService userService;

لتحقيق ذلك ، تحتاج إلى إنشاء حبة من خدماتك في ملف ServiceConfiguration الخاص بك. بعد ذلك ، ستحتاج إلى استيراد فئة ServiceConfiguration إلى فئة WebApplicationConfiguration الخاصة بك بحيث يمكنك Autowire أن الفول في وحدة التحكم الخاصة بك مثل هذا.

public class AccController {

    @Autowired
    private UserService userService;
} 

يمكنك العثور على POC على أساس تكوين جافا هنا example


يعتمد على ما إذا كنت قد ذهبت إلى طريق التعليقات التوضيحية أو مسار تعريف XML.

لنفترض أن لديك الفاصوليا المحددة في applicationContext.xml :

<beans ...>

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

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

</beans>

يحدث الاستقراء عند بدء تشغيل التطبيق. لذلك ، في fooController ، التي ترغب في استخدام فئة UserServiceImpl ، يمكنك UserServiceImpl عليها كما يلي:

public class FooController {

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

    // rest of class goes here
}

عندما يرى Spring @Autowired ، @Autowired Spring عن فئة تطابق الخاصية في التطبيق @Autowired ، @Autowired تلقائيًا. إذا كان لديك أكثر من 1 وحدة من وحدات UserService ، فستحتاج إلى تأهيل أي منها يجب استخدامه.

إذا قمت بما يلي:

UserService service = new UserServiceImpl();

لن يلتقط @ Autowired إلا إذا قمت بتعيينه بنفسك.





ioc-container