مرحبًا بك في درس مثال الربيع لـ IoC. إطار الربيع يعتمد على مبدأ Inversion of Control. إدخال التبعية هو التقنية المستخدمة لتنفيذ IoC في التطبيقات.
إدخال الربيع
اليوم سنتعرف على حاوية IoC للربيع. سنتعرف أيضًا على Bean الربيع. أدناه جدول المحتويات للانتقال السريع إلى أقسام مختلفة من درس IoC للربيع.
حاوية Spring IoC
الـــــنشء الــــمعنـــــي هو الآليــة لتحقيـــق الفصــل بين تبعيـــة الــكائنات. لتحقيق فصـــل تبعيــة وربط ديناميكي للكائنات في وقت التشغيل، يتم حقن تبعيات الكائنات بواسطة كائنات تجميع أخرى. حاوية الـــنشء في سبرينغ هي البرنامج الذي يحقن التبعيات في كائن ويجعله جاهزًا للاستخدام. لقد نظرنا بالفعل في كيفية استخدام حقن التبعيات في سبرينغ لتنفيذ الفصل بين تبعيات في تطبيقاتنا. فئات حاوية الـــنشء في سبرينغ جزء من حزم org.springframework.beans
و org.springframework.context
. توفر حاوية الـــنشء في سبرينغ طرقًا مختلفة لفصل تبعيات الكائن. BeanFactory
هو الواجهة الأساسية لحاوية الـــنشء في سبرينغ. ApplicationContext
هي الواجهة الفرعية لواجهة BeanFactory
التي توفر ميزات سبرينغ AOP، i18n وما إلى ذلك. بعض واجهات الأطفال المفيدة لـ ApplicationContext
هي ConfigurableApplicationContext
و WebApplicationContext
. يوفر إطار العمل سبرينغ عددًا من فئات التنفيذ المفيدة لـ ApplicationContext التي يمكننا استخدامها للحصول على سياق سبرينغ ومن ثم الكائن Spring. بعض تنفيذات ApplicationContext المفيدة التي نستخدمها هي؛
- AnnotationConfigApplicationContext: إذا كنا نستخدم سبرينغ في تطبيقات جافا مستقلة ونستخدم التعليمات البرمجية للتكوين، فيمكننا استخدام هذا لتهيئة الحاوية والحصول على كائنات الفول.
- ClassPathXmlApplicationContext: إذا كان لدينا ملف تكوين الفول الصويا في تطبيق مستقل، يمكننا استخدام هذه الفئة لتحميل الملف والحصول على كائن الحاوية.
- FileSystemXmlApplicationContext: يشبه هذا الفئة ClassPathXmlApplicationContext باستثناء أنه يمكن تحميل ملف تكوين XML من أي مكان في نظام الملفات.
- AnnotationConfigWebApplicationContext و XmlWebApplicationContext لتطبيقات الويب.
عادةً ما إذا كنت تعمل على تطبيق Spring MVC وكان تطبيقك مضبوطًا لاستخدام إطار Spring، فإن حاوية Spring IoC تُهيأ عند بدء التطبيق وعند طلب فول الصويا، يتم حقن التبعيات تلقائيًا. ومع ذلك، بالنسبة لتطبيق مستقل، تحتاج إلى تهيئة الحاوية في مكان ما في التطبيق ثم استخدامها للحصول على فول الصويا.
Spring Bean
فول الصويا في Spring ليس شيئًا خاصًا، أي كائن في إطار Spring نقوم بتهيئته من خلال حاوية Spring يُسمى فول الصويا. يمكن أن يكون أي فئة Java POJO عادية فول صويا إذا تم تهيئتها لتهيئتها من خلال الحاوية عن طريق توفير معلومات تكوين الفول.
نطاقات Spring Bean
هناك خمسة نطاقات محددة لفولادات Spring.
- مفرد – سيتم إنشاء مثيل واحد فقط من الفولاد لكل حاوية. هذا هو النطاق الافتراضي لفولادات الربيع. عند استخدام هذا النطاق، تأكد من عدم وجود متغيرات فرعية مشتركة للحاصر وإلا فقد يؤدي ذلك إلى مشاكل عدم تطابق البيانات.
- prototype – سيتم إنشاء مثيل جديد في كل مرة يتم فيها طلب الفولاد.
- طلب – هذا هو نفس نطاق النموذج، ومع ذلك، فإنه يهدف إلى استخدام تطبيقات الويب. سيتم إنشاء مثيل جديد من الفولاد لكل طلب HTTP.
- جلسة – سيتم إنشاء فولاد جديد لكل جلسة HTTP بواسطة الحاوية.
- جلسة عالمية – يتم استخدام هذا لإنشاء فولادات الجلسة العالمية لتطبيقات البوابة.
إطار Spring قابل للتمديد ويمكننا إنشاء نطاقات خاصة بنا أيضًا. ومع ذلك، في معظم الأحيان نكون على ما يرام مع النطاقات المقدمة من الإطار.
تكوين فولاد Spring
إطار Spring يوفر ثلاث طرق لتكوين الفولادات المستخدمة في التطبيق.
- تكوين قائم على التعليقات – عن طريق استخدام التعليقات @Service أو @Component. يمكن توفير تفاصيل النطاق مع تعليق @Scope.
- تكوين قائم على XML – عن طريق إنشاء ملف XML لتكوين فول الفاصوليا الربيعية. إذا كنت تستخدم إطار Spring MVC ، يمكن تحميل التكوين القائم على XML تلقائيًا عن طريق كتابة بعض الشفرة الأساسية في ملف web.xml.
- تكوين قائم على الجافا – بدءًا من الربيع 3.0 ، يمكننا تكوين فول الفاصوليا الربيعية باستخدام برامج جافا. بعض التعليقات الهامة المستخدمة لتكوين الجافا هي @Configuration، @ComponentScan و @Bean.
مشروع مثالي على البنية الرئيسية لـ Spring IoC و Spring Bean
لنلقِ نظرة على جوانب مختلفة من حاوية Spring IoC وتكوينات Spring Bean مع مشروع Spring بسيط. كمثال، أنا أنشئ مشروع Spring MVC في بيئة Spring Tool Suite. إذا كنت جديدًا على بيئة Spring Tool Suite و Spring MVC، يرجى قراءة برنامج تعليمي Spring MVC مع برنامج تعليمي Spring Tool Suite. تبدو الهيكل النهائي للمشروع كما في الصورة أدناه. دعونا نلقِ نظرة على مكونات مشروع Spring IoC و Spring Bean واحدًا تلو الآخر.
تكوين Spring Bean بناءً على XML
MyBean هو فئة Java POJO بسيطة.
package com.journaldev.spring.beans;
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ملف تكوين Spring XML
كود servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.journaldev.spring" />
<beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean>
</beans:beans>
لاحظ أن MyBean يتم تكوينه باستخدام العنصر bean
مع نطاق كونها فريدة.
تكوين Spring Bean بناءً على التعليمات البرمجية
package com.journaldev.spring.beans;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class MyAnnotatedBean {
private int empId;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
}
تم تكوين MyAnnotatedBean باستخدام @Service وتم تعيين النطاق للطلب.
فئة تحكم Spring IoC
سوف تتولى فئة HomeController معالجة طلبات HTTP لصفحة البداية للتطبيق. سنقوم بحقن بيناتنا النابعة من Spring إلى هذه الفئة المتحكمة من خلال حاوية WebApplicationContext.
package com.journaldev.spring.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.beans.MyAnnotatedBean;
import com.journaldev.spring.beans.MyBean;
@Controller
@Scope("request")
public class HomeController {
private MyBean myBean;
private MyAnnotatedBean myAnnotatedBean;
@Autowired
public void setMyBean(MyBean myBean) {
this.myBean = myBean;
}
@Autowired
public void setMyAnnotatedBean(MyAnnotatedBean obj) {
this.myAnnotatedBean = obj;
}
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
System.out.println("MyBean hashcode="+myBean.hashCode());
System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
وصف النشر
نحتاج إلى تكوين تطبيقنا لإطار Spring بحيث يتم تحميل بيانات التكوين وتهيئة السياق.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
تقريبًا جميع التكوينات أعلاه هي شفرة نموذجية يتم إنشاؤها تلقائيًا بواسطة أداة STS.
تشغيل تطبيق مثال Spring IoC Bean
الآن عندما تقوم بتشغيل تطبيق الويب، ستتم تحميل صفحة البداية وستتم طباعة السجلات التالية في وحدة التحكم عند تحديث الصفحة عدة مرات.
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106
لاحظ أن MyBean تم تكوينه ليكون Singleton ، لذلك يقوم المحتوى بإرجاع نفس النسخة دائمًا ويتم الحصول على الأكواد الهاش دائمًا بنفس القيمة. بالمثل ، يتم إنشاء نسخة جديدة من MyAnnotatedBean مع قيمة هاش مختلفة لكل طلب.
تكوين Java Based Spring Bean
بالنسبة لتطبيقات الواجهة المستخدم الرسومية ، يمكننا استخدام التكوين القائم على التوضيحات بالإضافة إلى التكوين القائم على XML. المتطلب الوحيد هو تهيئة السياق في أي مكان في البرنامج قبل استخدامه.
package com.journaldev.spring.main;
import java.util.Date;
public class MyService {
public void log(String msg){
System.out.println(new Date()+"::"+msg);
}
}
MyService هو فئة Java بسيطة تحتوي على بعض الطرق.
package com.journaldev.spring.main;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {
@Bean
public MyService getService(){
return new MyService();
}
}
فئة التكوين القائمة على التوضيحات التي ستُستخدم لتهيئة حاوية Spring.
package com.journaldev.spring.main;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyMainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
MyConfiguration.class);
MyService service = ctx.getBean(MyService.class);
service.log("Hi");
MyService newService = ctx.getBean(MyService.class);
System.out.println("service hashcode="+service.hashCode());
System.out.println("newService hashcode="+newService.hashCode());
ctx.close();
}
}
A simple test program where we are initializing the AnnotationConfigApplicationContext
context and then using getBean()
method to get the instance of MyService. Notice that I am calling getBean method two times and printing the hashcode. Since there is no scope defined for MyService, it should be a singleton and hence hashcode should be the same for both the instances. When we run the above application, we get following console output confirming our understanding.
Sat Dec 28 22:49:18 PST 2013::Hi
service hashcode=678984726
newService hashcode=678984726
إذا كنت تبحث عن التكوين القائم على XML ، فقط قم بإنشاء ملف تكوين XML لـ Spring ثم قم بتهيئة السياق باستخدام مقتطف الكود التالي.
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MyService app = context.getBean(MyService.class);
هذا كل شيء بالنسبة لبرنامج تعليمي عن مثال Spring IoC وتفاصيل تكوين Bean. قم بتنزيل مشروع Spring IoC و Spring Bean من الرابط أدناه واستمتع بتجربته لفهم أفضل.
المرجع: صفحة Spring.IO لـ IOC
Source:
https://www.digitalocean.com/community/tutorials/spring-ioc-bean-example-tutorial