أحييك يا هابر!
ستكون هذه المقالة مفيدة لأولئك الذين بدأوا بالفعل في تعلم Java وحتى تمكنوا من تحقيق بعض النجاح في فهم Java Core ، والآن سمعت كلمة Spring. وربما ، حتى ولو لمرة واحدة: تظهر معرفة إطار الربيع ، على الأقل ، في أوصاف العديد من الوظائف الشاغرة لليهوديين. ستساعدك هذه المقالة على تسلق الخطوة الأولى: لفهم الفكرة العامة لمثل هذا الإطار الشعبي.
لنبدأ من بعيد. هناك شيء مثل انعكاس التحكم ، باللغة الروسية - انعكاس التحكم ، في شكل مختصر - IoC. IoC هو أحد المبادئ التي تجعل كودنا أقرب إلى الرخاوة. IoC هو تفويض جزء من مسؤولياتنا إلى عنصر خارجي.
هناك تطبيقات مختلفة لنهج IoC ، نحن مهتمون بواحد منها - Dependency Injection ، حقن التبعية. ما هذا ، الاسم يتحدث عن نفسه ، لذلك سأحاول الكشف عنه باستخدام مثال. نكتب تطبيقًا يعمل على أتمتة تشغيل سلسلة من المتاجر. هناك فئات متجر (متجر) والبائع (البائع). البائع فئة لديه حقل من نوع متجر - المتجر الذي يعمل البائع. لذلك نحن نواجه الإدمان: البائع يعتمد على Shop. الآن دعنا نفكر في كيفية دخول كائن Shop إلى كائن البائع؟ هناك خيارات:
- قم بتنفيذها من خلال المصمم وعلى الفور ، عند إنشاء البائع ، حدد المتجر الذي يعمل فيه:
public class Seller { private Shop shop; public Seller(Shop shop) { this.shop = shop; } }
- قم بإنشاء واضع وتعيين المتجر للبائع باستخدام مكالمته:
public class Seller { private Shop shop; public void setShop(Shop shop) { this.shop = shop; } }
طريقتين المذكورة هي تنفيذ Dependency Injection. وأخيراً ، وصلنا إلى الربيع: إنه يوفر طريقة أخرى لحقن التبعيات.
بشكل عام ، Spring هو مجموعة واسعة جدًا من المكتبات في العديد من المناسبات. هناك Spring MVC لإنشاء تطبيقات الويب بسرعة ، و Spring Security لتنفيذ التفويض في التطبيق ، و Spring Data للعمل مع قواعد البيانات وأكثر من ذلك بكثير. لكن Spring IoC يقف وحيدا - هذا هو النوع الأساسي من الربيع الذي ينفذ الموضوع الذي ندرسه - حقن التبعية. يستحق ربيع IoC الانتباه في بداية دراسة مكتبات الربيع لسبب آخر. كما سترى في عملية العمل العملي مع أنواع أخرى من الربيع ، لجميع الينابيع الأخرى ، يستخدم ربيع IoC كإطار عمل.
سنبدأ تقديمنا لبرنامج Spring IoC مع المصطلح الرئيسي: الفول. في أبسط الكلمات
الحبة عبارة عن كائن فئة تم إنشاؤه بواسطة Spring والذي يمكن تضمينه كقيمة حقل في كائن آخر.
هل تريد كلمات أكثر تعقيدا؟ ورجاء:
الحبة عبارة عن عنصر صنف ، وهو عنصر برنامج كامل مع وظيفة عمل محددة أو وظيفة Spring داخلية ، يتم التحكم في دورة حياتها بواسطة حاوية الحاوية.
كما فهمت بالفعل ، لكي يتمكن Shop من تنفيذ Shop ، يجب أن يصبح Shop سلة مهملات. هناك عدة طرق لإخبار التطبيق عن الكائنات التي لها حق فخور في أن يطلق عليها اسم beans ، وكلها تقودنا إلى مفهوم ApplicationContext.
ApplicationContext هو قلب الربيع. كقاعدة عامة ، يتم إنشاؤه في بداية التطبيق ("يرتفع") ويتحكم في دورة حياة الفاصوليا. لذلك ، يطلق عليه أيضًا حاوية حاوية.
نحن نصل إلى الشيء الرئيسي. كيف نحتاج إلى إعادة كتابة فصولنا حتى يستبدل Spring IoC وخادم ApplicationContext حقل Shop لكائن البائع؟ مثل هذا:
@Component public class Shop { }
@Component public class Seller { @Autowired private Shop shop; }
هل هو بسيط؟ أسهل بكثير! أنيق؟ هو عليه. هنا حدث ما يلي: أخبر المكون التوضيحي Spring أن الفصل الذي تمت توضيحه عبارة عن حاوية. طلب التعليق التوضيحي Autowired إلى الربيع استبدال قيمة في الحقل بتعليقات توضيحية. هذه العملية تسمى الحقن. ما القيمة الدقيقة التي سيتم استبدالها؟ مزيد من المعلومات حول هذا الموضوع لاحقًا ، أولاً ، سنعرف كيف تصبح الفصول حاوية بشكل عام.
نحن نعلم بالفعل أنه في بداية التطبيق ، يجب أن يرتفع الوصي على جميع حبوب ApplicationContext. انه يخلق كل صناديق في وقت واحد. تقريبا كل شيء. الحقيقة هي أنه بشكل افتراضي ، فإن أي حبة لها نطاق خاصية intraspring في القيمة المفرد. Intraspringovoe ، لأنه بالمعنى الحرفي للكلمة أنه ليس منفرد. هذا هو المفرد لفصل الربيع: عندما يتم رفع السياق ، فإن Spring ينشئ كائنًا واحدًا بالضبط من الفئة المحددة. إذا كنت تريد تغيير هذا السلوك - من فضلك ، يسمح لك Spring بالتحكم في وقت إنشاء الحبة ورقمها لفئة واحدة ، ولكن الآن لا يتعلق الأمر بذلك.
لذلك ، عند رفع ApplicationContext ، يتم إنشاء جميع الصناديق. دعنا نتعرف بالضبط على المكان الذي يعيش فيه السياق والأهم من ذلك: كيف يحدد الفئات التي سيتم إنشاء صناديق منها. هناك العديد من الخيارات ، للبساطة ، سنتحدث عن واحد منهم: التكوين باستخدام ملف xml. هنا مثال على ذلك:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:beans="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="product" class="main.java.Product"></bean> <context:component-scan base-package="main"/> </beans>
يوضح هذا الملف كيفية إنشاء الفول بطريقتين. أول واحد ، دعنا نقول ، هو دليل. ترى ، هناك علامة
الفاصوليا مع إشارة إلى الفصل. هذا هو الفول. من كل شيء مسجل في هذا الملف بعلامة
الفاصوليا ، سيتم إنشاء
الفاصوليا .
الطريقة الثانية هي أقل مطول. تذكر ، على الفصول الدراسية وضعنا التعليق التوضيحي للمكون. من بين جميع الفئات المشروحة بهذا التعليق التوضيحي ، سيتم إنشاء فاصوليا. بفضل هذا السطر من ملف xml:
<context:component-scan base-package="main"/>
تخبر الربيع: قم بفحص الحزمة الرئيسية بأكملها ومن كل ما سيبقى تعليق التعليقات التوضيحية للمكونات (أو التعليقات التوضيحية الأخرى التي هي مكونات المكون) ، قم بإنشاء صناديق. مدمجة ، أليس كذلك؟ نقول فقط الحزم التي تحتوي على الفئات التي سيتم إنشاء الفاصوليا منها ، وتوضح هذه الفئات.
يمكنك رفع السياق باستخدام ملف xml بسطر التعليمات البرمجية التالي:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
حيث beans.xml هو المسار إلى لقب xml الذي تمت مناقشته أعلاه.
مع خلق الفاصوليا برزت. كيف يقوم Spring بملء حقل Shop عند إنشاء بائع؟ عند رفع السياق ، يتم إنشاء كائن bin من الفئة Shop. يتم أيضًا إنشاء كائن حاوية من فئة البائع ؛ ويتم أيضًا تعليقه بواسطة المكون. أنه يحتوي على نوع متجر مشروح بواسطة Autowired. يخبر التعليق التوضيحي التلقائي - الربيع: تحتاج إلى حقن الصندوق في هذا الحقل. في حالتنا ، لدينا صندوق واحد فقط مناسب لهذا الدور ، وهذا هو ، الذي يتطابق مع نوع الحقل: هذا هو بن - مثيل لفئة المتجر. سيتم حقنه في كائن البائع ، كما هو مطلوب. أتفهم أن الأسئلة قد ارتفعت الآن مثل الديدان: ما الذي سيحدث إذا لم يجد Spring الحبة المرغوبة ، أو وجد العديد منها مناسبًا (لا سيما بالنظر إلى أنه يمكنك أيضًا الحقن عن طريق الواجهة ، وليس حسب الفئة). الربيع ذكي ، لكنه يتطلب نفس الشيء منا. يجب أن يكون لدينا إما حبة واحدة في النظام مناسبة لكل Autowired ، أو لتدريب Spring للعمل في مثل هذه الصراعات (نحن لا نتحدث عن هذا الآن ، لقد تعبت بالفعل ، أو ربطت ، أو المقالة على وشك الانتهاء).
لاحظ أن البائع هو أيضًا صندوق. إذا لم تكن حاوية ، ولكن تم إنشاؤها عن طريق جديد ، فلن يضخها أي شيء تلقائيًا.
ربما تفكر الآن في سبب أهمية كل هذه الصعوبات. لكن تخيل أن طلبنا ليس من فئتين ، ولكن لم تعد هناك عدة أوامر بحجم أكبر وإدارة التبعية هي المهمة الأكثر تافهة.
ربما تظن الآن كيف يتيح لك ربيع ، بسيط وموجز ، تنفيذ التبعيات. لكن تخيل حدوث خطأ ما وتحتاج إلى تصحيح التطبيق. لم يعد الأمر سهلاً ...
أخيرًا ، بضع تلميحات:
- إذا كنت قد نفذت المشروع وأصبحت الآن في حيرة من أمرك بشأن كيفية الحصول على صندوق من الربيع للنظر فيه ، فقم بهذا:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Seller seller = (Seller) context.getBean(Seller.class);
هذه طريقة قانونية للحصول على صندوق ، على الرغم من أن هذا في الواقع الحديث لا يتم في العادة. ولكن لدراسة الحالة يمكنك.
- بما أن Spring إطار عمل ، فأنت بحاجة إلى تضمينه في مشروعك. أقوم بإنشاء تطبيق باستخدام maven وأضف التبعيات الأساسية للنابض والسياق إلى ملف pom.xml.
يحتوي Spring IoC على فرص هائلة لإنشاء الفول وتكوينه وحقنه. لقد درسنا جزءًا صغيرًا من طرف الجبل الجليدي ، أحد طرق العمل مع الربيع ، لكنني آمل أن نتمكن من إلقاء نظرة فاحصة عليه والحصول على فكرة عامة عما يحدث.