في هذه المقالة الصغيرة سأحاول أن أشرح لماذا قمت بإنشاء هذه المكتبة؟ وكيف يتم تنفيذه؟
لقد عملت مع إطار عمل Java EE في العديد من المشاريع وفي معظمها لم تكن هناك قيود على الموارد المتاحة لتشغيل التطبيق ولكن في بعض الحالات النادرة كانت لدينا موارد محدودة وخاصة الذاكرة لنشر التطبيق على خدمة النشر لذلك عندما يتجاوز التطبيق الحد، ستؤدي خدمة النشر إلى إبطاء التطبيق في البداية، ثم إذا استمرت الخدمة فسوف تقوم بإيقاف تشغيله. كنا نستخدم إطار الربيع القديم دون حتى التمهيد الربيعي، وحاولنا استخدام مكتبة مختلفة ولكن الفرق كان ضئيلًا ولا قيمة له، وهنا بدأت فكرة إنشاء بديل زنبركي خفيف الوزن يركز على تقليل استهلاك الذاكرة قدر الإمكان .
كان هناك هدفان فقط في ذهني عندما بدأت بتصميم المكتبة:
1- تقليل استهلاك الذاكرة قدر الإمكان
2 - حاول استخدام Java EE API الموجود قدر الإمكان لجعل الانتقال إلى المكتبة سهلاً من وجهة نظر التعلم ومن تعقيد الانتقال في حد ذاته.
ومن خلال هذين الهدفين تمكنت من تقليل أثر الذاكرة لأحد تطبيقاتي بنسبة 40% تقريبًا وجعل الانتقال سهلاً وسريعًا لأنه مشابه للحلول الحالية.
إليك مستودع GitHub حتى تتمكن من التحقق من الكود أثناء القراءة.
تحتوي المكتبة ككل على العديد من الأجزاء (لقطة الشاشة أدناه)، معظم التنفيذ في الوحدة الرئيسية والتي تنقسم أيضًا إلى ثلاثة أنواع من الوحدات المستقلة: Core، JPA، Web. وحدات التطبيق مخصصة بشكل أساسي للتكامل، ووحدة البرنامج الإضافي عبارة عن مكون إضافي مخضرم للمساعدة في إنشاء الملفات الضرورية داخل أرشيف الحزمة حتى تعمل المكتبة بشكل صحيح
لذلك سنبدأ بالوحدة الأساسية التي تحتوي، كما يوحي الاسم، على الوظيفة الأساسية للمكتبة وهي حقن التبعية أو قلب التحكم.
من أجل تحقيق هذه الوظيفة، يبدأ أولاً بمسح مسار فئة التطبيق أثناء مرحلة الترجمة لجميع الفئات المشروحة التي يجب أن تديرها المكتبة لإنشاء تعريفات مكون للفئات المشروحة.
يحتوي تعريف المكون بشكل أساسي على جميع المعلومات التي سنحتاجها لإنشاء مثيل لكائن من هذه الفئة لاحقًا، مثل معلومات المنشئ، إذا كان هناك بعض أدوات الضبط مع تعليق توضيحي للحقن (يتم دعم حقن المنشئ والضبط فقط) إذا كان الفصل يحتوي على بعض الواجهات أو توسيع فئة أخرى، سيكون لدينا جميع المعلومات التي نحتاجها لإنشاء كائن من هذه الفئة (لقطة الشاشة أدناه).
وبعد ذلك، بعد أن نقوم بمسح جميع التعليقات التوضيحية لمسار الفئة وإنشاء كل تعريفات المكونات التي نحتاجها، سنقوم بتخزينها في مسار الفئة كملف JSON.
الوظيفة الثانية والرئيسية للوحدة الأساسية هي حقن التبعية وعكس التحكم الذي يعتمد على نمط تصميم المصنع، لذلك لدينا واجهة ApplicationContext التي تعمل في حد ذاتها على توسيع ComponentFactory الواجهة والطريقة الرئيسية لهذه الواجهة هي طريقة getComponent والتي ستعيد الكائن من اسم المكون.
كما ترون في لقطة الشاشة أعلاه أولاً، نحاول التحقق مما إذا كان المكون موجودًا في مكونات Singleton التي تمت تهيئتها بالفعل، وإذا لم يكن كذلك، نبدأ بالحصول على تعريف المكون من ملف JSON ثم نبدأ حلقة while احصل على كافة تبعيات المكون قبل تمرير تعريف المكون وتبعياته إلى مجمع المكونات للحصول على كائن كامل جاهز للحقن.
إن تنفيذ وحدة JPA مشابه جدًا لبيانات Spring JPA ولكنه ضئيل للغاية، والسبب في أنها متشابهة جدًا لأنني استخدمت بيانات Spring في العديد من المشاريع ووجدت أنها سهلة الاستخدام وكما قلت من قبل كنت أرغب في الانتقال إلى المكتبة لتكون سلسة وتتطلب عملاً أقل قدر الإمكان، لذا كان تنفيذ إصدار بيانات الربيع المصغر الخاص بي هو الخيار الأفضل.
يتم التنفيذ حول واجهة JpaRepository التي تحتوي على العمليات الأكثر شيوعًا لقاعدة البيانات مثل الحفظ والحذف والعثور على الكل... ومن أجل استخدام وحدة JPA تحتاج إلى توسيع هذه الواجهة وتوفير الكيان الذي يجب أن تديره هذه الواجهة و إنه معرف، ثم بعد توسيع الواجهة والتعليق التوضيحي باستخدام التعليق التوضيحي للمستودع، يمكنك تحديد الأساليب الخاصة بك والتعليق عليها باستخدام التعليق التوضيحي للاستعلام وتوفير استعلام JPQL، ثم ستقوم المكتبة في مرحلة الترجمة بإنشاء فئة كاملة الوظائف تنفذ هذه الواجهة.
ستقوم المكتبة أيضًا بإدارة جزء المعاملات من التطبيق، لذلك ستتم إدارة واجهة المستودع بأكملها وأي فئة مشروحة بالمعاملات بواسطة المكتبة من وجهة نظر المعاملات. لذلك، بالنسبة لأي مكون معاملات، ستقوم المكتبة بإنشاء وكيل لإدارة المعاملة استنادًا إلى التعليق التوضيحي للمعاملات وستقوم أيضًا بإدارة دورة حياة مدير الكيان.
نموذج الويب هو المسؤول عن إدارة كل جزء الويب الخاص بالتطبيق وهو حسب التصميم وحدة مستقلة مما يعني أنه يمكن استخدامه بشكل مستقل عن بقية الوحدات في المكتبة، كالعادة فهو مشابه جدًا في الاستخدام لبعض الوحدات مكتبة Java EE المألوفة مثل Spring web أو Jax-rs.
يعتمد التنفيذ على التعليق التوضيحي، لديك فئات مشروحة بتعليق توضيحي وحدة التحكم وداخل وحدة التحكم هذه ستجد طريقة مشروحة باستخدام PathMapping وستتعامل هذه الطرق مع مسار محدد أو محدد الطلب بناء على بعض المعايير مثل نوع الطلب، نوع المحتوى...
من الخارج ستبدو مشابهة جدًا للمكتبة الأخرى ولكن من الداخل يختلف الأمر لأن المكتبة ستقوم بتغيير فئات وحدة التحكم في وقت التشغيل لجعلها جميعًا تقوم بتوسيع BaseHttpServlet ، والذي يمتد أيضًا إلى HttpServlet وسيعمل كخادم عادي.
كما ترون في لقطة الشاشة أعلاه، نقوم أولاً بتهيئة المكون في طريقة init لإدخال جميع التبعيات باستخدام WebApplicationContext، وبعد ذلك سنتعامل مع جميع الطلبات الوصول إلى وحدة التحكم هذه باستخدام طريقة handleRequest، وبهذا الأسلوب سوف نستخدم واجهة برمجة تطبيقات servlet الحالية لإدارة وحدات التحكم، وهذا سيساعد في الحفاظ على انخفاض مساحة الذاكرة وتقليل الحمل أيضًا نظرًا لأن المكتبة تعمل كمكون إضافي لاستكمال عمل servlet API.
أولاً، نحاول تعيين الطلب إلى الطريقة الصحيحة وبعد ذلك، نحاول إدخال جميع المعلومات المطلوبة داخل الطريقة عن طريق الحصول على المعلومات إما من السياق أو من HttpServletRequest مثل الطلب المعلمة أو الرؤوس أو متغير المسار أو نص الطلب...
نقوم بتحويل كل هذه المعلومات ثم حقنها كمعلمة للطريقة عند طلبها ثم نقوم بتنفيذ الطريقة وتحويل النتيجة أو النتيجة بناءً على إنتاج PathMapping أو نوع المحتوى (بواسطة افتراضيًا هو application/Json) ثم نكتب المحتوى إلى HttpServletResponse.
أخيرًا، إذا حدث خطأ ما في العملية وتم طرح خطأ، فإننا نكتشف هذا الخطأ أو الاستثناء ونحاول التعامل معه بناءً على نوع الاستثناء، لدينا معالج استثناء للتعامل مع نوع مختلف من الاستثناء و يمكن للمستخدم أيضًا توفير المزيد من المعالج للتعامل مع أي استثناء بالطريقة التي يريدها.
الجزء الأخير والمهم هو المكون الإضافي المخضرم الذي سينشئ جميع الملفات الضرورية للتطبيق ليعمل بشكل صحيح وأيضًا لإنشاء حزمة الجرة أو الحرب.
أولاً، سيقوم البرنامج المساعد بفحص مسار الفصل والتبعيات للبحث في ملفات component-definitions-json، ومن هذه الملفات سيتم إنشاء:
lazy-application.json: يحتوي على جميع المكونات وتبعياتها للتطبيق
lazy-application.properties: يحتوي على قائمة وحدات التحكم والكيانات لذلك لا نحتاج إلى فحص مسار الفصل في وقت التشغيل.
وأخيرًا إذا كانت العبوة جرة سنحصل على الطبقة الرئيسية.
وأخيرًا قمنا بإنشاء ملف أرشيف الحزمة الذي سيحتوي على رمز التطبيق مع تبعياته والملفات التي أنشأناها في الخطوة السابقة.
حاولت عدم التعمق في التفاصيل لإبقاء المقالات قصيرة وليست معقدة جدًا للفهم، بالطبع الكود متاح على GitHub حتى تتمكن من اللعب به أيضًا. إذا كان لديك أي سؤال، قم بإسقاطه أدناه وسأحاول للرد عليهم.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3