التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة
افهم محملات الفئات الأساسية والمنصات والتطبيقات، واكتب ClassLoader مخصصًا
التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.
التسلسل الهرمي لـ ClassLoader
يستخدم JVM تسلسلًا هرميًا من ClassLoader. لكل مُحمِّل مُحمِّلٌ أب؛ وقبل أن يحاول تحميل فئة بنفسه، يفوّض المهمة إلى الأب، وفق نموذج التفويض إلى الأب أولًا.
Bootstrap ClassLoader
يحمّل Bootstrap ClassLoader فئات JDK الأساسية (java.lang.* وjava.util.*). وقد نُفِّذ باستخدام native code، وليس له أب من Java؛ لذلك تُرجع getParent() القيمة null.
ClassLoader cl = String.class.getClassLoader();
System.out.println(cl); // null (bootstrap ClassLoader)Platform ClassLoader (Java 9+)
يحمّل Platform ClassLoader (المعروف سابقًا باسم Extension ClassLoader) الوحدات من JDK التي لا تنتمي إلى مجموعة Bootstrap (java.sql وjava.xml وغيرهما). أما الأب فهو Bootstrap ClassLoader.
ClassLoader platform = ClassLoader.getPlatformClassLoader();
System.out.println(platform.getClass().getName());
// jdk.internal.loader.ClassLoaders$PlatformClassLoaderApplication (System) ClassLoader
يحمّل Application ClassLoader فئات التطبيق من مسار الفئات (-cp أو CLASSPATH). والأب هو Platform ClassLoader. وهو المُحمِّل الافتراضي لشفرة المستخدم.
ClassLoader app = ClassLoader.getSystemClassLoader();
System.out.println(app.getClass().getName());
// jdk.internal.loader.ClassLoaders$AppClassLoaderالتفويض إلى الأب أولًا
عند تحميل com.example.MyService، يطلب AppClassLoader أولًا من أبِه (Platform)، الذي يطلب بدوره من Bootstrap. ولا يحاول المُحمِّل الابن تحميل الفئة بنفسه إلا إذا عجز جميع الآباء عن تحميلها.
هوية الفئة وClassLoader
تُعد فئتان لهما الاسم نفسه، لكن حُمِّلتا بواسطة ClassLoader مختلفين، نوعين مختلفين. ويؤدي التحويل بينهما إلى إلقاء ClassCastException، وهذا مهم في أنظمة الإضافات وOSGi.
// Loaded by two different loaders → different Class objects
Class<?> c1 = loader1.loadClass("com.example.Plugin");
Class<?> c2 = loader2.loadClass("com.example.Plugin");
System.out.println(c1 == c2); // false!كتابة ClassLoader مخصص
وسِّع ClassLoader وتجاوز findClass(String name). اقرأ bytecode من مصدر مخصص (مثل JAR مشفّر أو الشبكة أو قاعدة بيانات)، ثم استدعِ defineClass.
public class EncryptedClassLoader extends ClassLoader {
public EncryptedClassLoader(ClassLoader parent) { super(parent); }
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] bytes = decrypt(readBytecodeFromVault(name));
return defineClass(name, bytes, 0, bytes.length);
}
}URL ClassLoader: التحميل من ملفات JAR
يحمّل URLClassLoader الفئات من قائمة بعناوين URL (مسارات ملفات أو عناوين HTTP). ويفيد ذلك في أنظمة الإضافات التي تضيف ملفات JAR أثناء التشغيل.
URL[] urls = { new File("plugins/my-plugin.jar").toURI().toURL() };
try (URLClassLoader loader = new URLClassLoader(urls, getClass().getClassLoader())) {
Class<?> cls = loader.loadClass("com.example.PluginImpl");
Plugin plugin = (Plugin) cls.getDeclaredConstructor().newInstance();
plugin.start();
}إغلاق ClassLoader
أغلِق URLClassLoader دائمًا عند الانتهاء، لأنه يُبقي ملفات JAR مفتوحة. ويسمح إغلاقه بحذف ملفات JAR أو تحديثها. استخدم try-with-resources.
التفويض إلى الابن أولًا (التحميل المعزول)
تعكس بعض الحاويات (Tomcat وSpring Boot fat JAR) التسلسل الهرمي: يحاول المُحمِّل الابن أولًا، ثم يعود إلى الأب فقط إذا لم يجد الفئة. ويعزل ذلك إصدارات المكتبات بين تطبيقات الويب.
تسرّبات ClassLoader
لا يمكن جمع classloader بواسطة GC إلا عندما لا تعود أي فئة حمّلها قابلة للوصول. وتُبقي الحقول الثابتة التي تحتفظ بكائنات من فئة محمّلة المُحمِّل حيًا، وهو تسرّب شائع عند إعادة النشر.
تحقق سريع
ماذا يفعل ClassLoader قبل أن يحاول تحميل الفئة بنفسه؟
مراجعة
التسلسل الهرمي من ثلاثة مستويات: Bootstrap ← Platform ← Application. يمنع التفويض إلى الأب أولًا تكرار الفئات. تتجاوز المُحمِّلات المخصصة findClass. استخدم URLClassLoader في أنظمة الإضافات. وأغلِق المُحمِّلات لمنع التسرّبات.
الأسئلة الشائعة
هل درس «التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة» مجاني؟
نعم — نص درس «التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.
ماذا ستتعلم في «التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة»؟
افهم محملات الفئات الأساسية والمنصات والتطبيقات، واكتب ClassLoader مخصصًا تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟
لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟
نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مراحل تحميل الفئات: التحميل والربط والتهيئة
- التسلسل الهرمي لـ ClassLoader ومحملات الفئات المخصصة
- فحص البايت كود باستخدام javap
- ترجمة JIT والترجمة متعددة المستويات