سؤال

فقط من باب الفضول، هل هناك أي مشاريع مفتوحة المصدر (مستقرة) لإنشاء أكواد Java البرمجية في وقت التشغيل بخلاف cglib؟ولماذا يجب أن أستخدمها؟

هل كانت مفيدة؟

المحلول

أسم

تم بناء CGLIB وجميع المكتبات الأخرى تقريبًا على ASM الذي يعمل بحد ذاته على مستوى منخفض جدًا.يعد هذا أمرًا رائعًا بالنسبة لمعظم الأشخاص حيث يتعين عليك فهم رمز البايت والقليل من رمز البايت JVMS لاستخدامه بشكل صحيح.لكن إتقان ASM هو بالتأكيد أمر مثير للاهتمام.لاحظ مع ذلك أنه بينما يوجد عظيم دليل ASM4, ، في بعض أجزاء واجهة برمجة التطبيقات، يمكن أن تكون وثائق javadoc موجزة جدًا إذا كانت موجودة على الإطلاق، ولكن يتم تحسينها.إنه يتبع عن كثب إصدارات JVM لدعم الميزات الجديدة.

ومع ذلك، إذا كنت بحاجة إلى التحكم الكامل، فإن ASM هو سلاحك المفضل.

ويشهد هذا المشروع تحديثات منتظمة.وفي وقت إجراء هذا التعديل، تم إصدار الإصدار 5.0.4 في 15 مايو 2015.

بايت الأصدقاء

Byte Buddy هي مكتبة جديدة إلى حد ما ولكنها توفر أي وظيفة توفرها CGLIB أو Javassist وأكثر من ذلك بكثير.يمكن تخصيص Byte Buddy بالكامل وصولاً إلى مستوى رمز البايت ويأتي مزودًا بلغة معبرة خاصة بالمجال تسمح برمز قابل للقراءة للغاية.

  • وهو يدعم جميع إصدارات JVM bytecode، بما في ذلك التغييرات الدلالية لـ Java 8 لبعض أكواد التشغيل فيما يتعلق بالطرق الافتراضية.
  • لا يبدو أن ByteBuddy تعاني من عيوب المكتبات الأخرى
  • شكلي للغاية
  • سريع جدا (المعيار شفرة)
  • اكتب API بطلاقة وآمنة
  • اكتب عمليات الاسترجاعات الآمنة

    تعتمد نصائح Javassist أو كود الأجهزة المخصصة على الكود الموجود في ملف عادي String وبالتالي فإن التحقق من الكتابة وتصحيح الأخطاء أمر مستحيل ضمن هذا الكود، بينما يسمح ByteBuddy بكتابة تلك التي تحتوي على Java خالصة وبالتالي يفرض عمليات التحقق من النوع ويسمح بتصحيح الأخطاء.

  • التعليقات التوضيحية مدفوعة (مرن)

    يمكن تكوين عمليات رد الاتصال للمستخدم باستخدام التعليقات التوضيحية التي تسمح بتلقي المعلمات المطلوبة في رد الاتصال.

  • متاح كوكيل

    يسمح منشئ الوكيل الأنيق باستخدام ByteBuddy كعامل نقي أو كعامل ربط.يسمح بنوع مختلف

  • موثقة بشكل جيد للغاية
  • الكثير من الأمثلة
  • كود نظيف، تغطية اختبارية بنسبة 94% تقريبًا
  • دعم أندرويد ديكس

ربما يكون الجانب السلبي الرئيسي هو أن واجهة برمجة التطبيقات (API) مطولة بعض الشيء بالنسبة للمبتدئين ولكنها مصممة كواجهة برمجة تطبيقات (API) قابلة للاشتراك على شكل DSL لتوليد الوكيل؛ليس هناك افتراضيات سحرية أو مشكوك فيها.عند معالجة كود البايت، فمن المحتمل أن يكون هذا هو الخيار الأكثر أمانًا والأكثر منطقية.أيضًا مع وجود أمثلة متعددة وبرنامج تعليمي كبير، فهذه ليست مشكلة حقيقية.

في أكتوبر 2015، حصلت هذه المشاريع على جائزة اختيار أوراكل ديوك.في هذا الوقت وصلت للتو إلى 1.0.0 معلما, ، وهو إنجاز كبير.

لاحظ أن تم استبداله CGLIB بواسطة بايت الأصدقاء في الإصدار 2.1.0.

جافاسيست

يعد javadoc الخاص بـ Javassist أفضل بكثير من CGLIB.واجهة برمجة التطبيقات الهندسية للفصل جيدة، لكن Javassist ليست مثالية أيضًا.على وجه الخصوص، ProxyFactory وهو ما يعادل CGLIB Enhancer تعاني أيضًا من بعض السلبيات، على سبيل المثال لا الحصر:

  • طريقة الجسر غير مدعومة بشكل كامل (أي تلك التي تم إنشاؤها لأنواع الإرجاع المتغيرة)
  • ClassloaderProvider هو حقل ثابت بدلاً من ذلك، ثم ينطبق على جميع المثيلات الموجودة داخل نفس أداة تحميل الفصل
  • كان من الممكن الترحيب بالتسمية المخصصة (مع فحص الجرار الموقعة)
  • لا توجد نقطة تمديد وجميع أساليب الاهتمام تقريبًا خاصة، وهو أمر مرهق إذا أردنا تغيير بعض السلوكيات
  • على الرغم من أن Javassist تقدم دعمًا لسمات التعليقات التوضيحية في الفئات، إلا أنها غير مدعومة فيها ProxyFactory.

على الجانب الموجه نحو الجوانب، يمكن للمرء إدخال التعليمات البرمجية في الوكيل، ولكن هذا النهج في Javassist محدود وعرضة للخطأ بعض الشيء:

  • تتم كتابة رمز الجانب في سلسلة Java عادية تجميع وانتاج في رموز التشغيل
  • لا يوجد فحص النوع
  • لا الأدوية العامة
  • لا لامدا
  • لا يوجد ملاكمة تلقائية

ومن المعروف أيضًا أن Javassist أبطأ من Cglib.ويرجع ذلك أساسًا إلى أسلوبه في قراءة ملفات الفئة بدلاً من قراءة الفئات المحملة مثل CGLIB.و ال تطبيق في حد ذاته من الصعب قراءته ليكون عادلاً؛إذا احتاج المرء إلى إجراء تغييرات في كود Javassist، فهناك فرص كثيرة لكسر شيء ما.

عانى Javassist من الخمول أيضًا، وانتقالهم إلى جيثب حوالي عام 2013 يبدو أنه أثبت فائدته لأنه يُظهر التزامات منتظمة ويسحب الطلبات من المجتمع.

لا تزال هذه القيود قائمة في الإصدار 3.17.1.تم رفع الإصدار إلى الإصدار 3.20.0، ومع ذلك يبدو أن Javassist ربما لا يزال يواجه مشكلات مع دعم Java 8.

جيتسكريبت

يبدو JiteScript وكأنه قطعة جديدة من تصميم DSL لـ ASM، وهذا يعتمد على أحدث إصدار ASM (4.0).الرمز يبدو نظيفا.

لكن لا يزال المشروع في مراحله الأولى، لذا يمكن تغيير واجهة برمجة التطبيقات/السلوك، بالإضافة إلى أن التوثيق سيئ.والتحديثات نادرة إن لم يتم التخلي عنها.

بروكسيتا

هذه أداة جديدة إلى حد ما ولكنها تقدم الأفضل على الإطلاق بشر واجهة برمجة التطبيقات.فهو يسمح بأنواع مختلفة من الوكلاء مثل وكلاء الفئات الفرعية (نهج cglib) أو النسيج أو التفويض.

على الرغم من أن هذا المنتج نادر إلى حد ما، إلا أنه لا توجد معلومات حول ما إذا كان يعمل بشكل جيد.هناك الكثير من الحالات الزاوية التي يجب التعامل معها عند التعامل مع الرمز الثانوي.

الجانب J

AspectJ هي أداة قوية جدًا لـ الجانب برمجة (فقط).يتعامل AspectJ مع كود البايت لتحقيق أهدافه بحيث تتمكن من تحقيق أهدافك به.ومع ذلك، يتطلب هذا التلاعب في وقت الترجمة؛عرض الربيع النسيج في وقت التحميل عبر وكيل منذ الإصدار 2.5, 4.1.x.

CGLIB

كلمة حول CGLIB تم تحديثها منذ طرح هذا السؤال.

CGLIB سريع جدًا، وهو أحد الأسباب الرئيسية لاستمرار وجوده، إلى جانب حقيقة أن CGLIB كان يعمل بشكل أفضل تقريبًا من أي بدائل حتى الآن (2014-2015).

بشكل عام، يجب على المكتبات التي تسمح بإعادة كتابة الفئات في وقت التشغيل تجنب تحميل أي أنواع قبل إعادة كتابة الفئة المقابلة.لذلك، لا يمكنهم الاستفادة من واجهة برمجة تطبيقات Java Reflection التي تتطلب تحميل أي نوع مستخدم في الانعكاس.بدلاً من ذلك، يتعين عليهم قراءة ملفات الفصل عبر الإدخال والإخراج (وهو ما يعطل الأداء).وهذا يجعل Javassist أو Proxetta على سبيل المثال أبطأ بشكل ملحوظ من Cglib الذي يقرأ ببساطة الأساليب عبر واجهة برمجة تطبيقات الانعكاس ويتجاوزها.

ومع ذلك، لم يعد CGLIB قيد التطوير النشط.كانت هناك إصدارات حديثة ولكن هذه التغييرات اعتبرها الكثيرون غير مهمة ولم يقوم معظم الأشخاص بالتحديث مطلقًا إلى الإصدار 3 منذ أن قدمت CGLIB بعض البق الشديد في الإصدارات الأخيرة ما لم يبني الثقة حقًا. قام الإصدار 3.1 بإصلاح الكثير من مشكلات الإصدار 3.0 (منذ إعادة حزم إطار عمل Spring 4.0.3) الإصدار 3.1).

كما أن كود مصدر CGLIB هو بالأحرى جودة رديئة بحيث لا نرى مطورين جدد ينضمون إلى مشروع CGLIB.للحصول على انطباع عن نشاط CGLIB، راجع القائمة البريدية.

لاحظ أن متابعة أ اقتراح على القائمة البريدية guice, ، CGLIB متاح الآن على جيثب لتمكين المجتمع من مساعدة المشروع بشكل أفضل، يبدو أنه يعمل (الالتزامات المتعددة وطلبات السحب، ci، المخضرم المحدث)، ومع ذلك لا تزال معظم المخاوف قائمة.

في الوقت الحالي، هناك عمل على الإصدار 3.2.0، وهم يركزون جهودهم على Java 8، ولكن حتى الآن يتعين على المستخدمين الذين يريدون دعم Java 8 استخدام الحيل في وقت الإنشاء.لكن التقدم بطيء جداً.

ولا يزال من المعروف أن CGLIB تعاني من تسرب ذاكرة PermGen.لكن ربما لم يتم اختبار المشاريع الأخرى لسنوات عديدة.

تجميع معالجة التعليقات التوضيحية للوقت

هذا ليس وقت تشغيل بالطبع، ولكنه جزء مهم من النظام البيئي، ومعظم استخدامات إنشاء التعليمات البرمجية لا تحتاج إلى إنشاء وقت تشغيل.

بدأ هذا مع Java 5 الذي جاء مزودًا بأداة سطر الأوامر المنفصلة لمعالجة التعليقات التوضيحية: apt, وبدءًا من Java 6، تم دمج معالجة التعليقات التوضيحية في مترجم Java.

في وقت ما، طُلب منك تمرير المعالج بشكل صريح، والآن مع ServiceLoader النهج (فقط أضف هذا الملف META-INF/services/javax.annotation.processing.Processor إلى الجرة) يمكن للمترجم اكتشاف معالج التعليقات التوضيحية تلقائيًا.

هذا النهج في إنشاء التعليمات البرمجية له عيوبه أيضًا، فهو يتطلب الكثير من العمل وفهم لغة Java وليس الرمز الثانوي.تعد واجهة برمجة التطبيقات (API) هذه مرهقة بعض الشيء، وبما أن أحدها عبارة عن مكون إضافي في المترجم، فيجب عليه توخي الحذر الشديد لجعل هذا الرمز هو رسالة الخطأ الأكثر مرونة وسهولة في الاستخدام.

أكبر ميزة هنا هي أنه يتجنب أي تبعية أخرى في وقت التشغيل، وقد تتجنب تسرب الذاكرة الدائم.ويتمتع المرء بالتحكم الكامل في الكود الذي تم إنشاؤه.

خاتمة

في 2002 حددت CGLIB معيارًا جديدًا للتعامل مع الكود الثانوي بسهولة.العديد من الأدوات والمنهجيات (CI، التغطية، TDD، وما إلى ذلك) المتوفرة لدينا في الوقت الحاضر لم تكن متوفرة أو لم تكن ناضجة في ذلك الوقت.تمكنت CGLIB من أن تكون ذات صلة لأكثر من عقد من الزمان ;هذا إنجاز لائق جدًا.لقد كان سريعًا وبواجهة برمجة تطبيقات سهلة الاستخدام بدلاً من التعامل مع أكواد التشغيل مباشرة.

لقد حددت معيارًا جديدًا فيما يتعلق بإنشاء التعليمات البرمجية ولكن في الوقت الحاضر لم يعد الأمر كذلك بسبب تغير البيئة والمتطلبات، وكذلك تغيرت المعايير والأهداف.

تم تغيير JVM وسيتغير في إصدارات Java (7/8/9/10) الحديثة والمستقبلية (الاستدعاء الديناميكي، والطرق الافتراضية، وأنواع القيم، وما إلى ذلك).قام ASM بترقية واجهة برمجة التطبيقات (API) والمكونات الداخلية الخاصة به بانتظام لمتابعة هذه التغييرات، لكن CGLIB وآخرين لم يستخدموها بعد.

على الرغم من أن معالجة التعليقات التوضيحية تحظى بالاهتمام، إلا أنها ليست مرنة مثل إنشاء وقت التشغيل.

اعتبارًا من عام 2015، بايت الأصدقاءبينما جديدة إلى حد ما على الساحة - تقديم الأكثر إقناعا يبيع نقاط لتوليد وقت التشغيل.معدل تحديث لائق، والمؤلف لديه معرفة وثيقة بالأجزاء الداخلية لكود Java بايت.

نصائح أخرى

Javassist .

إذا كنت بحاجة إلى جعل وكلاء، نلقي نظرة على المشتركة بالوكالة - ويستخدم كلا CGLIB وJavassit.

وأنا أفضل الخام ASM ، التي أعتقد أنها تستخدم من قبل cglib على أي حال. انها مستوى منخفض، ولكن وثائق هي <م> رائعة ، وبمجرد أن تعتاد على ذلك فسوف يكون الطيران.

لإجابة سؤالك الثاني، يجب عليك استخدام الجيل الرمز عند انعكاس وكلاء ديناميكية بدأت تشعر شكله قليلا معا، وكنت في حاجة الى حل الصخور الصلبة. في الماضي لقد أضاف حتى خطوة الجيل الشفرة في عملية الإنشاء في الكسوف، إعطائي فعال الإبلاغ وقت الترجمة من أي شيء وكل شيء.

وأعتقد أنه أكثر منطقية لاستخدام Javassist بدلا من ذلك من cglib. مثلا javasist يعمل تماما مع الجرار وقعت على عكس cglib. الى جانب ذلك، هذا الكبرى كمشروع السبات قررت التوقف عن استخدام cglib لصالح Javassist .

وصمم CGLIB وتنفيذها منذ أكثر من عشر سنوات في اوب وعصر ORM. حاليا لا أرى أي أسباب لاستخدام ذلك، وأنا لا تحتفظ هذه المكتبة بعد الآن (باستثناء إصلاحات الشوائب التطبيقات القديمة بلدي). في الواقع كل حالات الاستخدام CGLIB لدي أي وقت مضى رأيتها هي مكافحة أنماط في البرمجة الحديثة. وينبغي أن يكون تافها لتنفيذ نفس الوظائف عن طريق أي لغة البرمجة JVM على سبيل المثال رائع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top