ملفات تعريف البيئة (@Profile)
ملفات تعريف البيئة (@Profile)
كل تطبيق جاد يعمل في أكثر من بيئة واحدة: حاسوب المطوّر المحلي، وخادم ضمان الجودة المشترك، وبيئة الاختبار المرحلي (staging)، والإنتاج. تحتاج كل بيئة عادةً إلى بنية تحتية مختلفة — قاعدة بيانات H2 في الذاكرة محليًا، ومثيل PostgreSQL حقيقي في الاختبار المرحلي، وبيانات اعتماد مشفّرة في الإنتاج. تكرار فئات الإعداد لكل بيئة أو إخفاء كل اختلاف خلف غابة من جمل if أمر هش ومعرّض للأخطاء.
تحلّ آلية ملفات التعريف (profiles) في Spring هذه المشكلة بأناقة. الملف التعريفي هو تجميع منطقي مُسمّى. تُعلّق الـ beans أو فئات الإعداد بأكملها بـ @Profile، وتُفعّل ملفًا تعريفيًا واحدًا أو أكثر عند بدء التشغيل، فيُسجّل Spring فقط الـ beans التي تتطابق ملفاتها التعريفية. كل ما عداها يُتجاهل — بأمان، على مستوى الحاوية، لا بشروط وقت التشغيل المبعثرة في كودك.
إعلان Bean مرتبط بملف تعريفي محدد
تقبل التعليقة التوضيحية @Profile سلسلة نصية واحدة أو مصفوفة من السلاسل. الـ bean المُعلَّق بـ @Profile("dev") لا يُسجَّل إلا عندما يكون ملف التعريف dev نشطًا.
يُقيّم Spring التعليقة @Profile عند بدء تشغيل الحاوية. إن لم يتطابق أي ملف تعريفي نشط، فلن يُسجَّل الـ bean ببساطة. وإن حاول كودك حقن DataSource دون محدِّد ولم يكن أيّ ملف تعريفي نشطًا، ستحصل على NoSuchBeanDefinitionException عند بدء التشغيل — وهو تمامًا نمط الفشل الصحيح: صاخب ومبكّر، قبل تقديم أي طلب.
تعليق فئة إعداد بأكملها
عندما تكون فئة كاملة ذات صلة ببيئة واحدة فقط، عليق الفئة نفسها بدلًا من كل طريقة @Bean على حدة. هذا أكثر وضوحًا ويجعل القصد جليًا:
@Profile على الفئة، ترث كل طريقة @Bean بداخلها هذا الملف التعريفي. حين يكون على طريقة @Bean واحدة، يُقيَّد ذلك الـ bean وحده. استخدم التعليق على مستوى الفئة حين يكون الإعداد بأكمله خاصًا ببيئة ما؛ واستخدم التعليق على مستوى الطريقة حين تمزج بين beans مشتركة وأخرى خاصة بملف تعريفي في الفئة ذاتها.
تعبيرات ملف التعريف — دمج الملفات التعريفية منطقيًا
منذ Spring 5.1، تدعم السلسلة النصية داخل @Profile لغة تعبير بسيطة تتيح لك كتابة شروط دون الحاجة إلى تعليقات متعددة:
@Profile("dev")— نشط حين يكونdevنشطًا.@Profile("!prod")— نشط حين لا يكونprodنشطًا (مفيد لحواجز الأمان).@Profile("dev | staging")— نشط حين يكون أيٌّ منهما نشطًا (منطق OR).@Profile("cloud & eu-west")— نشط فقط حين يكون كلاهما نشطَين (منطق AND).@Profile("(dev | staging) & !legacy")— تعبيرات منطقية مُجمَّعة.
@Profile("!prod") أكثر دفاعية من تعليق التنفيذ الحقيقي بـ @Profile("prod"). إن شغّل أحدهم التطبيق دون أي ملف تعريفي، يُحمَّل الـ stub — وهو أكثر أمانًا بكثير من تحميل تكامل الإنتاج عن طريق الخطأ.
تفعيل ملفات التعريف
يقرأ Spring الملفات التعريفية النشطة من عدة مصادر، يُقيَّم كلٌّ منها وفق الأولوية. أكثر الآليات شيوعًا:
1. في application.properties / application.yml:
هذا مريح للإعدادات المحلية الافتراضية لكنه لا ينبغي أن يُودَع في نظام التحكم بالإصدار وهو يشير إلى prod — وإلا سيُشير كل مطوّر يستنسخ المستودع إلى الإنتاج عن غير قصد.
2. كخاصية نظام JVM (الأعلى أولوية من سطر الأوامر):
3. كمتغير بيئة لنظام التشغيل (المفضّل للحاويات وCI/CD):
تتّبع متغيرات البيئة قواعد الربط المرنة (relaxed-binding) في Spring Boot: تصبح النقاط شرطات سفلية وتُكتب الأسماء بحروف كبيرة. هذا يتوافق مع اصطلاحات Docker وKubernetes ومعظم منصات CI، مما يجعله الآلية الإنتاجية المعيارية للتفعيل.
4. برمجيًا — مفيد في الاختبارات:
يمكن تفعيل ملفات تعريف متعددة في آنٍ واحد. افصل بينها بفواصل في الخاصية أو متغير البيئة، أو مرّر قيمًا متعددة إلى @ActiveProfiles:
ملفات الخصائص الخاصة بكل ملف تعريفي
يُمدّد Spring Boot آلية ملفات التعريف لتشمل ملفات الخصائص تلقائيًا. إن كان ملف التعريف النشط هو staging، يحمّل Boot كلًّا من application.properties وapplication-staging.properties (أو ما يعادلهما من YAML). تتجاوز قيم الملف الخاص بالملف التعريفي قيم الملف الأساسي.
application-prod.properties في نظام التحكم بالإصدار هو المكان المناسب للإعدادات الإنتاجية غير السرية (مستويات التسجيل، كشف نقاط النهاية)، لكن كلمات مرور قواعد البيانات ومفاتيح API يجب أن تأتي من متغيرات البيئة أو مدير أسرار — حتى في ملفات الخصائص الخاصة بالملفات التعريفية.
ملف التعريف الافتراضي
الـ beans المُعلَّقة بـ @Profile("default") تُسجَّل حين لا يكون أي ملف تعريفي نشطًا. هذا شبكة أمان مفيدة: قدّم بديلًا معقولًا (عادةً stub محلي) حتى يبدأ التطبيق بنظافة حتى دون ملف تعريفي صريح، بدلًا من إلقاء خطأ bean مفقود.
الخلاصة
تمنحك التعليقة @Profile طريقة Spring-managed أصيلة لتنويع رسم الـ beans حسب البيئة. علّق الـ beans أو فئات الإعداد بأكملها باسم ملف تعريفي؛ استخدم صياغة التعبيرات (!، |، &) لشروط أكثر ثراءً. فعّل ملفات التعريف عبر متغيرات البيئة للحاويات، وعبر application.properties للإعدادات الافتراضية للمطوّرين، وعبر @ActiveProfiles في الاختبارات. ادمج @Profile مع ملفات الخصائص الخاصة بكل ملف تعريفي (application-{profile}.properties) لتبقي إعداد كل بيئة مُجمَّعًا وقابلًا للقراءة وخاليًا من جمل if في وقت التشغيل.