الخدمات مع provides/uses
فصل المكونات باستخدام محمّل الخدمات
الخدمات مع provides/uses درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
فصل المكونات باستخدام الخدمات
يمكن للوحدات التعاون من دون الاعتماد على تطبيقات بعضها بعضًا، باستخدام نمط محمّل الخدمات.
تعلن وحدة أنها uses واجهة خدمة، وتعلن وحدة أخرى أنها provides تطبيقًا لها. ويتولى JVM ربطهما معًا.
الأدوار الثلاثة
تتضمن الخدمة ثلاثة أطراف:
- واجهة الخدمة: العقد الموجود في إحدى الوحدات
- المزوّد: وحدة توفّر تطبيقًا
- المستهلك: وحدة تحمّل التطبيقات وقت التشغيل
واجهة الخدمة
ابدأ بتعريف العقد. إنها مجرد واجهة Java عادية في حزمة مُصدَّرة، بحيث يستطيع كل من المزوّدين والمستهلكين الرجوع إليها.
package com.example.spi;
public interface Codec {
String name();
byte[] encode(String input);
}يعلن المستهلك uses
تعلن وحدة المستهلك أنها uses الواجهة. ويخبر ذلك JPMS بأن الوحدة ستبحث عن التطبيقات من خلال ServiceLoader.
module com.example.app {
requires com.example.spi;
uses com.example.spi.Codec;
}يعلن المزوّد provides
تعلن وحدة المزوّد الواجهة التي تطبقها باستخدام provides ... with ...، مع تسمية صنفها الفعلي.
module com.example.base64 {
requires com.example.spi;
provides com.example.spi.Codec
with com.example.base64.Base64Codec;
}تطبيق المزوّد
صنف التطبيق عبارة عن Java عادية. ويجب أن يكون عامًا، وأن يوفّر إما مُنشئًا عامًا بلا معاملات أو طريقة عامة ثابتة provider().
package com.example.base64;
import com.example.spi.Codec;
import java.util.Base64;
public class Base64Codec implements Codec {
public String name() { return "base64"; }
public byte[] encode(String input) {
return Base64.getEncoder().encode(input.getBytes());
}
}التحميل باستخدام ServiceLoader
يطلب المستهلك وقت التشغيل من ServiceLoader.load(Codec.class) جميع المزوّدين المتاحين، ثم يتكرر عليهم، من دون ربط وقت الترجمة بأي تطبيق.
import com.example.spi.Codec;
import java.util.ServiceLoader;
public class App {
public static void main(String[] args) {
ServiceLoader<Codec> loader = ServiceLoader.load(Codec.class);
for (Codec codec : loader) {
System.out.println("Found codec: " + codec.name());
}
}
}لماذا يُعد هذا قويًا
لا يسمّي المستهلك صنف أي مزوّد أبدًا. ضع وحدة مزوّد جديدة في مسار الوحدات، وسيُكتشف المزوّد تلقائيًا.
يتيح ذلك إنشاء بُنى إضافات وفصلًا نظيفًا للتبعيات.
مصنع provider()
إذا احتاج الإنشاء إلى منطق خاص، فاعرض طريقة عامة ثابتة provider() بدلًا من مُنشئ بلا معاملات. يستدعيها JPMS للحصول على المثيل.
package com.example.base64;
import com.example.spi.Codec;
public class CodecFactory {
public static Codec provider() {
return new Base64Codec();
}
}مزوّدون متعددون
يمكن لوحدات كثيرة أن توفّر الواجهة نفسها. يعيد ServiceLoader جميع هذه الوحدات، مما يتيح للمستهلك الاختيار حسب الاسم أو الأولوية أو الإمكانات.
أضف المزوّدين أو أزلهم من دون تعديل شفرة المستهلك.
التدفق عبر المزوّدين
منذ Java 9، يوفّر ServiceLoader الطريقة stream()، التي تنتج مقابض Provider يمكنك تصفيتها قبل إنشاء المثيلات، وهو أمر مفيد عندما يكون الإنشاء مكلفًا.
import com.example.spi.Codec;
import java.util.ServiceLoader;
public class App {
public static void main(String[] args) {
Codec chosen = ServiceLoader.load(Codec.class).stream()
.map(ServiceLoader.Provider::get)
.filter(c -> c.name().equals("base64"))
.findFirst()
.orElseThrow();
System.out.println("Using: " + chosen.name());
}
}تحقق سريع
تذكّر التوجيه الذي يستخدمه كل دور.
مراجعة
تعلّمت نمط خدمات الوحدات:
- ثلاثة أدوار: واجهة الخدمة، والمزوّد، والمستهلك
- المستهلك:
uses؛ والمزوّد:provides ... with - تُحمّل التطبيقات وقت التشغيل عبر
ServiceLoader - يحتاج المزوّد إلى مُنشئ عام بلا معاملات أو إلى
provider()ثابتة
التالي: ترحيل مشروع موجود إلى الوحدات.
الأسئلة الشائعة
هل درس «الخدمات مع provides/uses» مجاني؟
نعم — نص درس «الخدمات مع provides/uses» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «الخدمات مع provides/uses»؟
فصل المكونات باستخدام محمّل الخدمات تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «الخدمات مع provides/uses»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- module-info.java
- requires وexports
- الخدمات مع provides/uses
- الترحيل إلى الوحدات