حقن القيم والمجموعات والخصائص
حقن القيم والمجموعات والخصائص
يُتيح حقن المُنشئ والحقن عبر الضابط (setter) ربط الـ Beans ببعضها. لكن التطبيقات الحقيقية تحتاج أيضًا إلى تهيئة قيم عددية — مهل الانتظار، عناوين URL، أعلام الميزات، أحجام التجمّعات — وبيانات منظّمة كقوائم أصول مسموح بها أو خرائط تُربط المناطق بالعملات. يوفّر Spring آليتين متكاملتين لهذا: الإضافة التوضيحية @Value والربط الآمن نوعيًا عبر @ConfigurationProperties. إنّ معرفة متى وكيف تستخدم كلًّا منهما يُميّز التهيئة النظيفة القابلة للصيانة عن تشابك السلاسل السحرية.
الإضافة التوضيحية @Value
تحلّ @Value تعبيرًا بلغة Spring Expression Language أو نمطًا لملء العناصر النائبة للخصائص، وتحقن النتيجة في حقل أو معامل مُنشئ أو وسيط ضابط. تعتمد الصيغة الأكثر شيوعًا على نحو ${...} للبحث عن مفتاح في Environment، الذي يجمع جميع مصادر الخصائص (خصائص النظام، ومتغيرات بيئة نظام التشغيل، وapplication.properties، وملفات YAML، والمصادر المخصصة) وفق ترتيب أولوية محدد.
تُزوّد صيغة النقطتين — ${key:defaultValue} — قيمةً احتياطية تُستخدم عندما يكون المفتاح غائبًا. بدون قيمة افتراضية، يُرمى استثناء BeanCreationException عند بدء التشغيل في حال غياب المفتاح، وهو السلوك المطلوب للإعدادات الإلزامية. استخدم القيم الافتراضية فقط للعناصر الاختيارية حقًا.
ملف application.properties المقابل:
application-{profile}.properties > application.properties > ملفات @PropertySource > القيم الافتراضية. هذا يعني إمكانية تجاوز أي خاصية وقت النشر دون المساس بملف JAR — وهو مبدأ أساسي من مبادئ تطبيق Twelve-Factor.
تعبيرات SpEL داخل @Value
يُفعّل نحو #{...} لغة Spring Expression Language التي تتجاوز البحث البسيط. يمكنك استدعاء توابع، والوصول إلى Beans أخرى، وإجراء عمليات حسابية، واستدعاء أدوات ثابتة:
تعبيرات SpEL قوية، لكن أبقها بسيطة داخل @Value. المنطق المعقد ينتمي إلى تابع مصنع @Bean أو فئة خدمة، لا إلى سلسلة تعليق توضيحي يصعب قراءتها ويستحيل تصحيح أخطائها بنقطة توقف.
حقن القوائم والمصفوفات
تُقسَّم قيمة الخاصية المفصولة بفواصل تلقائيًا إلى List أو مصفوفة عندما يكون الحقل المُحقن من النوع المقابل:
تتولّى ConversionService في Spring عملية التقسيم وتحويل النوع. تنجح نفس التقنية مع القوائم الرقمية مثل List<Integer> وint[] — يُحوَّل كل رمز مميّز إلى النوع المستهدف.
حقن الخرائط (Maps)
تتطلب الخرائط صيغة SpEL لأن الخاصية البسيطة key=value لا تستطيع وحدها حمل بنية الخريطة:
يُقيّم #{} الخارجي قيمة الخاصية كتعبير SpEL، ويوسّع ${} الداخلي القيمة أولًا. هذا التعشيش مقصود: يُوسَّع ${locale.currency.map} إلى السلسلة الحرفية {en_US:'USD',...}، ثم يُحلّلها SpEL كخريطة.
@ConfigurationProperties (انظر أدناه). حقن الخريطة عبر SpEL هشّ — خطأ إملائي في ملف الخصائص ينتج خطأ تحليل غامضًا عند بدء التشغيل بدلًا من رسالة تحقق واضحة.
تحميل ملفات الخصائص الخارجية باستخدام @PropertySource
لا يجب أن تعيش الخصائص في application.properties فقط. يمكنك توجيه Spring إلى أي مورد على مسار الفئات أو نظام الملفات:
يُفيد ignoreResourceNotFound = true للملفات الاختيارية التي توجد فقط في بيئات معينة (أسرار الإنتاج، التجاوزات الخاصة بالمطوّرين). بدونه، يُفشل الملف المفقود تحميل السياق.
الربط الآمن نوعيًا باستخدام @ConfigurationProperties
عندما تنتمي مجموعة من الإعدادات ذات الصلة معًا — تجمّع قاعدة بيانات، خادم بريد إلكتروني، بوابة دفع — فإن @ConfigurationProperties هو الأداة الصحيحة. إنها تربط بادئة نطاق الخصائص بكائن Java عادي (POJO)، مع تحويل نوع كامل وتحقق ودعم الإكمال التلقائي في بيئات التطوير.
لاحظ أن mail.start-tls في ملف الخصائص يُعيَّن إلى setStartTls في الفئة. يُطبّع Relaxed Binding في Spring الكتابة بالشرطة (kebab-case) وcamelCase والشرطات السفلية والأحرف الكبيرة — فهي كلها متكافئة لأغراض الربط. لهذا يمكن لمتغير بيئة نظام التشغيل MAIL_PASSWORD إشباع خاصية باسم mail.password.
@Validated واستخدم قيود Bean Validation مثل @NotBlank و@Min و@Max و@Pattern وما شابهها على الحقول. سترفض Spring البدء إذا انتهكت القيم المرتبطة هذه القيود — وهو أفضل بكثير من اكتشاف خطأ في التهيئة أثناء التشغيل.
@Value مقابل @ConfigurationProperties — قاعدة القرار
- استخدم
@Valueللقيم المعزولة الفردية — مهلة انتظار واحدة، أو علم ميزة، أو مفتاح API يُستخدم في Bean واحد فقط. إنها سريعة ولا تتطلب فئة إضافية. - استخدم
@ConfigurationPropertiesلأي مجموعة متجانسة من ثلاثة إعدادات مترابطة أو أكثر. إنها توثّق نفسها، وتتحقق عند بدء التشغيل، وتُولّد البيانات الوصفية لبيئة التطوير لتوفير الإكمال التلقائي فيapplication.properties. - لا تتشتّت نفس البادئة عبر عشرات من تعليقات
@Valueفي Beans مختلفة. مركزها في فئة@ConfigurationPropertiesواحدة وحقن تلك الفئة أينما احتجت إليها.
الخلاصة
تُعدّ @Value بصيغة ${key:default} نقطة الدخول لحقن القيم العددية والمجموعات البسيطة؛ بينما يُفتح صيغة #{spel} آفاق الخرائط والقيم المحسوبة. تُتيح @PropertySource تحميل ملفات خصائص إضافية. لمجموعات الإعدادات المترابطة، تقدّم @ConfigurationProperties أمانًا نوعيًا وتحقّقًا وربطًا مرنًا — وينبغي أن تكون خيارك الافتراضي لكل ما يُشكّل نطاقًا للتهيئة. تُبقي هذه الآليات معًا التهيئة خارج كودك وتحت سيطرة بيئة النشر.