مشروع: ضبط الإعدادات لبيئات متعددة
مشروع: ضبط الإعدادات لبيئات متعددة
على مدار هذا البرنامج التعليمي درستَ كل عنصر من عناصر إعداد Spring بمعزل عن غيره: الملفات الشخصية (profiles) ومصادر الخصائص و@Value و@Conditional وتجريد Environment. يجمع هذا الدرس الختامي كل هذه العناصر في مشروع Spring Boot 3 واقعي. الهدف هو قاعدة شيفرة تعمل بشكل متطابق على حاسوب المطوّر ومشغّل اختبارات CI وخادم الإنتاج — دون تعديل يدوي لأي ملف، ودون كتل معطّلة بعلامات التعليق، ودون مسارات شيفرة خاصة ببيئات مدفونة في منطق الأعمال.
البنية المستهدفة
يكشف التطبيق عن واجهة برمجية REST مدعومة بقاعدة بيانات علائقية. ويستخدم إرسال البريد الإلكتروني بشكل غير متزامن ويتكامل مع بوابة دفع خارجية. يجب أن تستوفي استراتيجية الإعداد أربعة متطلبات:
- بيئة التطوير (Dev) — بدء تشغيل سريع، قاعدة بيانات H2 في الذاكرة، طباعة البريد الإلكتروني على وحدة التحكم، بوابة الدفع معطّلة.
- بيئة الاختبار (Test) — حتمية ولا مكالمات شبكية، H2 أو Testcontainers، جميع العملاء الخارجيين مستبدَلون بنسخ مزيّفة.
- بيئة الاستعراض (Staging) — تعكس بنية الإنتاج ولكن تستخدم بيانات اعتماد غير حساسة وبوابة دفع اختبارية.
- بيئة الإنتاج (Prod) — PostgreSQL، SMTP حقيقي، بوابة دفع حقيقية، حدود اتصال صارمة، لا سجلات تصحيح.
تخطيط ملفات الخصائص
يحلّ Spring Boot هرمية محددة من مصادر الخصائص. بالنسبة لملف شخصي يسمى prod، يحمّل (بترتيب الأولوية، الأعلى أولًا):
- متغيرات بيئة نظام التشغيل وخصائص JVM النظامية (
-Dkey=value) application-prod.properties(أو.yml)application.properties(الإعدادات الافتراضية الأساسية)
احتفظ فقط بالقيم المستقلة حقًا عن البيئة في الملف الأساسي. كل عنوان URL خاص ببيئة معينة أو سر يخصها ينتمي إلى ملف الملف الشخصي أو — والأفضل — إلى متغير بيئة على الجهاز المستهدف.
${ENV_VAR} في application-prod.properties Spring بحل القيمة من البيئة الفعلية عند بدء التشغيل. يمكن إيداع الملف نفسه بأمان في نظام التحكم بالإصدارات لأنه لا يحتوي على أي بيانات اعتماد فعلية.
اختيار الحبوب بحسب الملف الشخصي
الحبوب التي تتطلب بنية تحتية حقيقية تنتمي وراء الملفات الشخصية. أنشئ فئة إعداد مخصصة لكل تكامل خارجي:
تعتمد خدمات الأعمال على الواجهة AppMailSender — لا على التنفيذ الملموس. يحقن Spring الحبة الصحيحة تلقائيًا بناءً على الملف الشخصي النشط. لا if/else في شيفرة الأعمال، ولا علامات منطقية تُفحص في وقت التشغيل.
ربط خصائص الإعداد بفئة مكتوبة بأنواع
تشتيت حقن @Value عبر فئات كثيرة يجعل سطح الإعداد صعب الرؤية وصعب التحقق. اجمع الخصائص ذات الصلة في سجل @ConfigurationProperties واحد:
يتحقق Spring Boot من الخصائص عند بدء التشغيل. إذا كانت payment.gateway.base-url مفقودة في ملف شخصي، يفشل التطبيق فورًا برسالة خطأ واضحة بدلًا من رمي NullPointerException في عمق معالج الطلب.
spring-boot-configuration-processor إلى بنائك. يولّد بيانات وصفية لبيئة التطوير المتكاملة حتى يحصل application.properties على إكمال تلقائي وتوثيق لكل فئة @ConfigurationProperties. إنه معالج تعليقات وقت الترجمة فحسب — لا تكلفة في وقت التشغيل.
حبوب البنية التحتية الشرطية
بعض الحبوب لا ينبغي إنشاؤها أصلًا إذا كانت علامة الميزة معطّلة. استخدم @ConditionalOnProperty لهذا الغرض:
يضمن matchIfMissing = true على حبة الاختبار أنه إذا كانت الخاصية غائبة — مثلًا في اختبار وحدة لا يحمّل أي ملف خاص بملف شخصي — تُستخدم النسخة الآمنة لا العميل الحقيقي.
تفعيل الملفات الشخصية
ثمة ثلاث طرق معيارية لتفعيل ملف شخصي:
- وسيطة JVM (CI / Docker):
-Dspring.profiles.active=prod - متغير بيئة (12-factor / Kubernetes):
SPRING_PROFILES_ACTIVE=prod - تعليق اختبار:
@ActiveProfiles("test")على فئة اختبار JUnit
في النشر المعتمد على الحاويات، يُعدّ تعيين SPRING_PROFILES_ACTIVE كمتغير بيئة في مواصفات الحاوية أو أمر تشغيل Docker الأسلوبَ المفضّل: إذ يبقي ملف JAR متطابقًا عبر البيئات وتحدد البيئة دورها بنفسها.
إعداد الاختبار
تحتاج اختبارات التكامل إلى شريحة إعداد خاصة بها. يوفر Spring Boot الجمعَ بين @SpringBootTest وملف application-test.properties مخصص:
application-test.properties الخاص بالاختبار ضمن src/test/resources، لا src/main/resources. سيعثر عليه Spring Boot تلقائيًا حين يكون الملف الشخصي للاختبار نشطًا، ولن يُدرَج أبدًا في ملف JAR الإنتاجي.
الخلاصة: القواعد التي تُبقيه صامدًا
يلتزم إعداد Spring Boot متعدد البيئات الذي يصمد عمليًا بمجموعة صغيرة من القواعد:
- ملف أساسي واحد للإعدادات الافتراضية المشتركة فعلًا؛ وملف شخصي واحد لكل بيئة للتجاوزات.
- الأسرار في متغيرات البيئة فقط — لا في الملفات الموجودة في نظام التحكم بالإصدارات.
- حبوب مدفوعة بالملف الشخصي عوضًا عن فحوصات
if/elseفي وقت التشغيل داخل منطق الأعمال. @ConfigurationPropertiesمكتوب بأنواع لجميع الخصائص المخصصة — تُتحقق عند بدء التشغيل وتكتمل تلقائيًا في بيئة التطوير.- الملف الشخصي للاختبار في
src/test/resources— سريع وحتمي ومعزول تمامًا عن البنية التحتية الحقيقية.
حين تُتّبع هذه القواعد، يمكنك تسليم نفس ملف JAR لأي بيئة والوثوق بأنه سيضبط نفسه بشكل صحيح من السياق المحيط به — وهو بالضبط ما تطلبه منهجية التطبيقات ذات الاثني عشر عاملًا وما تتوقعه خطوط أنابيب النشر الحديثة.