ApplicationContext في العمل التطبيقي
ApplicationContext في العمل التطبيقي
قرأت عن حاوية IoC وتعريفات الـ beans بصورة نظرية. حان الآن وقت كتابة كود حقيقي: تشغيل ApplicationContext وسحب الـ beans منه وفهم أي تنفيذ ملموس تختار في كل موقف. يتركز هذا الدرس على الشيئين اللذين يقوم بهما المطورون يوميًا مع الحاوية — اختيار فئة ApplicationContext المناسبة واسترجاع الـ beans بشكل صحيح.
التطبيقات الثلاثة الأساسية لـ ApplicationContext
يأتي Spring مزودًا بعدة تطبيقات لـ ApplicationContext. ستصطدم بثلاثة منها باستمرار:
AnnotationConfigApplicationContext— الخيار المعياري لتطبيقات Java المستقلة واختبارات التكامل وأي مشروع يُهيّئ Spring بفئات@Configurationو/أو فحص المكونات. لا يعتمد على حاوية servlet أو مورد على مسار الفئات.ClassPathXmlApplicationContext— يحمّل تعريفات beans بصيغة XML من مسار الفئات. ستراه أساسًا في قواعد الكود القديمة. فهمه يساعدك على قراءة المشاريع القديمة وترحيلها.GenericWebApplicationContext/AnnotationConfigWebApplicationContext— يُستخدم داخل حاوية Servlet (Tomcat أو Jetty). ينشئDispatcherServletالخاص بـ Spring MVC أحد هذين تلقائيًا؛ نادرًا ما تبنيه بنفسك.
SpringApplication.run() كائن AnnotationConfigServletWebServerApplicationContext (أو النسخة التفاعلية) خلف الكواليس. لن تستدعي المنشئ بنفسك، لكن يمكنك تحويل الـ ConfigurableApplicationContext المُعاد لفحصه. كل ما يرد هنا ينطبق مباشرةً.
تشغيل السياق: AnnotationConfigApplicationContext
أبسط طريقة لبدء حاوية Spring هي تمرير فئة @Configuration الخاصة بك إلى المنشئ:
يقبل المنشئ فئة @Configuration واحدة أو أكثر، أو يمكنك تمرير سلسلة اسم الحزمة الأساسية لتفعيل فحص المكونات:
استخدم try-with-resources متى ما تحكمت في دورة الحياة. ApplicationContext يُوسّع Closeable، لذا تستدعي كتلة try الـ close() تلقائيًا، مما يُشغّل الإيقاف السلس لجميع الـ beans المفردة.
استرجاع الـ Beans: ثلاثة أشكال من getBean()
تُعرض واجهة BeanFactory (التي تُوسّعها ApplicationContext) عدة أشكال مُحمَّلة. معرفة متى يُناسب كل شكل تتجنّب أخطاء يصعب اكتشافها:
ما يحدث عند استدعاء getBean()
لـ bean مفرد (singleton) — النطاق الافتراضي — يُعيد Spring نفس المثيل المهيّأ بالكامل في كل مرة. لا توجد تكلفة أداء لاستدعاء getBean() مرارًا — إنها مجرد بحث في خريطة بعد التهيئة الأولى:
لـ bean من نوع prototype، يُنشئ Spring مثيلًا جديدًا في كل استدعاء لـ getBean(). لا يُخزَّن هذا المثيل مؤقتًا وتنتهي إدارة دورة حياته بعد الإنشاء — فأنت المسؤول عن استدعاء أي منطق تنظيف بنفسك.
getBean() هي نقاط دخول التطبيق (مثل main()) وكود تهيئة إطار العمل والاختبارات.
سرد الـ Beans وفحصها
تُوفّر ApplicationContext عدة توابع للفحص قيّمة في التصحيح والأدوات:
يمكنك أيضًا التحقق مما إذا كان الـ bean قد هُيّئ أو الاستعلام عن نوعه دون تشغيل التهيئة باستخدام ctx.getType("beanName"). هذه أدوات قوية خلال التصحيح — ضعها في CommandLineRunner مؤقت في تطبيق Spring Boot لفحص السياق الحي.
مثال عملي واقعي
إليك إعداد مدمج لكنه واقعي — أداة سطر أوامر لمعالجة الطلبات — يُوضّح كيف تتفاعل التشغيل والاسترجاع والإغلاق:
لاحظ أن main() تستدعي getBean() مرة واحدة فقط — للحصول على الخدمة الجذرية. كل شيء آخر يتدفق عبر حقن المنشئ. هذا هو النمط الصحيح.
استخدام ClassPathXmlApplicationContext (للقراءة في الكود القديم)
إن ورثت قاعدة كود من عصر ما قبل Spring 3 أو احتجت إلى استخدام ملف إعداد XML قديم، فكود التشغيل يبدو شبه متطابق:
يقع ملف XML على مسار الفئات (مثل src/main/resources/applicationContext.xml). الواجهة البرمجية لاسترجاع الـ beans متطابقة — فقط سطر التشغيل يتغير. عند تحديث مثل هذا المشروع، تكون خطوتك الأولى عادةً استبدال هذا السطر بـ AnnotationConfigApplicationContext بعد ترحيل الـ beans إلى فئات @Configuration.
الخلاصة
تُعدّ ApplicationContext الحاوية التي تتعامل معها يوميًا، حتى وإن كان Spring Boot يُخفيها خلف SpringApplication.run(). اعلم أن AnnotationConfigApplicationContext هو خيارك الافتراضي للتطبيقات المبنية على التعليقات التوضيحية خارج Boot؛ وأنك تسترجع الـ beans بالنوع في المقام الأول؛ وأن استدعاءات getBean() المباشرة تنتمي فقط إلى نقطة الدخول الخارجية. تبني الدروس التالية على هذا الأساس بفحص التسمية والمحددات وكيفية التعامل مع عدة beans من النوع ذاته.