سؤال

أنا أعمل مع تطبيقات JSF/FaceLets كبيرة جدًا تستخدم Spring لإدارة DI/Bean. تتمتع تطبيقاتي ببنية معيارية وأنا أبحث حاليًا عن مقاربات لتوحيد modularization.

هدفي هو تكوين تطبيق ويب من عدد من الوحدات النمطية (ربما حسب بعضها البعض). قد تحتوي كل وحدة على ما يلي:

  • الطبقات؛
  • الموارد الثابتة (الصور ، CSS ، البرامج النصية) ؛
  • قوالب الوجه.
  • الفاصوليا المدارة - سياقات تطبيق الربيع ، مع الطلب والجلسة والفاصوليا المغطاة بالتطبيق (البديل هو الفاصوليا المدارة JSF) ؛
  • Servlet API Stuff - Servlets ، المرشحات ، المستمعين (هذا اختياري).

ما أود تجنبه (بأي ثمن تقريبًا) هو الحاجة إلى نسخ أو استخراج موارد الوحدة النمطية (مثل قوالب الوجه) إلى الحرب أو تمديد web.xml بالنسبة إلى Servlets للوحدة النمطية ، المرشحات ، إلخWEB-INF/lib, bundles, plugins, ، ...) لتوسيع تطبيق الويب باستخدام هذه الوحدة.

حاليًا أقوم بحل هذه المهمة باستخدام حل تعليمي مخصص يعتمد بشكل كبير على استخدام موارد ClassPath:

  • يخدم الموارد الخاصة Servlet موارد ثابتة من ClassPath Resources (JARS).
  • يتيح حل موارد FaceLets الخاص تحميل قوالب Facelet من موارد ClassPath.
  • يقوم الربيع بتحميل سياقات التطبيق عبر النمط classpath*:com/acme/foo/module/applicationContext.xml - هذا يحمل سياقات التطبيق المحددة في الجرار الوحدة النمطية.
  • أخيرًا ، هناك زوج من Servlets والمرشحات المفوضية لطلب معالجة Servlets والمرشحات التي تم تكوينها في سياقات تطبيق الربيع من الوحدات النمطية.

آخر الأيام قرأت الكثير عن OSGI وكنت أفكر ، كيف (وإذا) يمكنني استخدام OSGI كنهج موحد للمواد. كنت أفكر في كيفية حل المهام الفردية باستخدام OSGI:

  • الموارد الثابتة - حزم OSGI التي تريد تصدير الموارد الثابتة تسجيل أ ResourceLoader مثيلات مع سياق الحزمة. مركزي ResourceServlet يستخدم لوادر الموارد هذه لتحميل الموارد من الحزم.
  • قوالب الوجه - على غرار أعلاه ، مركز ResourceResolver يستخدم الخدمات المسجلة بواسطة حزم.
  • الفاصوليا المدارة - ليس لدي أي فكرة كيفية استخدام تعبير مثل #{myBean.property} إذا myBean يتم تعريفه في واحدة من الحزم.
  • Servlet API Stuff - استخدم شيئًا مثل Webextender/Pax Web لتسجيل Servlets و Filters وما إلى ذلك.

أسئلتي هي:

  • هل أخترع دراجة هنا؟ هل هناك حلول قياسية لذلك؟ لقد وجدت ذكرًا لشرائح الربيع ولكن لم أتمكن من العثور على الكثير من الوثائق حول هذا الموضوع.
  • هل تعتقد أن OSGI هي التكنولوجيا المناسبة للمهمة الموصوفة؟
  • هل رسم تطبيق OSGI الخاص بي أكثر أو أقل صحة؟
  • كيف ينبغي التعامل مع الفاصوليا المدارة (وخاصة نطاق الطلب/الجلسة)؟

سأكون ممتنًا بشكل عام لتعليقاتك.

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

المحلول

ما تهدف إلى القيام به يبدو أنه قابل للتنفيذ ، مع بعض التحذيرات:

طبقة العرض: أولاً ، تبدو طبقة العرض الخاصة بك محصورة قليلاً. هناك طرق أخرى لتعديل مكونات JSF باستخدام مكونات مخصصة من شأنها تجنب الصداع الذي ينطوي عليه محاولة إنشاء شيء دراماتيكي مثل الفاصوليا المدارة في وقت متأخر.

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

التبعيات: أنا قلق قليلاً من وصفك للوحدات النمطية على أنها "ربما يعتمد على بعضها البعض". من المحتمل أنك (آمل) أن تعرف هذا بالفعل ، ولكن يجب أن تشكل تبعياتك رسم بياني حشيش موجه. بمجرد تقديم تبعية دائرية ، فأنت تطلب عالمًا من الأذى من حيث القدرة على الصيانة في نهاية المطاف. واحدة من أكبر نقاط الضعف في OSGI هي ذلك لا منع التبعيات الدائرية ، لذلك الأمر متروك لك لفرض هذا. وإلا فإن تبعياتك سوف تنمو مثل Kudzu وتخنق تدريجيا بقية النظام البيئي لنظامك.

servlets: fuhgeddaboudit. لا يمكنك المتأخر من Servlets في تطبيق ويب ، ليس حتى يتم إنتاج Servlet 3.0 (كما أشار Pascal). لإطلاق خدمة فائدة منفصلة ، ستحتاج إلى وضعه في تطبيقه الخاص.


حسنًا ، كثيرًا للتحذيرات. دعونا نفكر في كيفية عمل هذا:

لقد حددت وحدة JSF الخاصة بك لتفعلها ... ماذا ، بالضبط؟ دعنا نعطيه غرضًا محددًا ، تافهة إلى حد ما: شاشة تسجيل الدخول. لذلك يمكنك إنشاء شاشة تسجيل الدخول الخاصة بك ، وتراجعها في وقت متأخر باستخدام OSGI في تطبيقك و ... ثم ماذا؟ كيف يعرف التطبيق وظيفة تسجيل الدخول موجودة ، إذا لم تقم بتعريفها في صفحة .jspx الخاصة بك؟ كيف يعرف التطبيق الانتقال إلى شيء لا يمكن معرفته هناك؟

هناك طرق للتغلب على هذا باستخدام تشمل مشروط وما شابه (على سبيل المثال ، <c:if #{loginBean.notEmpty}>) ، ولكن ، كما قلت ، تصبح الأمور شعرًا قليلاً عندما توجد تسجيل الدخول المدار في وحدة أخرى قد لا يتم تقديمها إلى التطبيق حتى الآن. في الواقع ، ستحصل على استثناء من Servlet إلا إذا كان هذا loginbean موجودًا. إذن ماذا تفعل؟

يمكنك تحديد واجهة برمجة التطبيقات في إحدى وحداتك. يجب تحديد جميع الفاصوليا المدارة التي تنوي مشاركتها بين الوحدات النمطية كواجهات في طبقة API هذه. ويجب أن تحتوي جميع وحداتك على تطبيقات افتراضية لأي من هذه الواجهات التي تنوي استخدامها. ويجب مشاركة واجهة برمجة التطبيقات هذه بين جميع الوحدات النمطية القابلة للتشغيل البيني. ثم يمكنك استخدام OSGI و Spring لتسليم الفاصوليا المحددة مع تنفيذها.

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

عادةً ما أعتبر الفاصوليا المدارة جزءًا من طبقة العرض ، وبالتالي فأنا أستخدمها فقط للعرض المنطق ، وتفويض كل شيء آخر إلى طبقة الخدمة. إن جعل الفاصوليا المدارة في وقت متأخر من المرتبطة ، في رأيي ، تروج لها خارج طبقة العرض وإلى منطق العمل. هناك سبب يركز جميع هذه البرامج التعليمية على الخدمات: لأنه في معظم الوقت تريد أن تفكر في ما سيتطلبه تطبيقك لتشغيله "بلا رأس" ، ومدى سهولة "الجلد" الخاص بك مثال ، أردت تشغيله ، بكل وظائفه ، على هاتف Android.

لكن يبدو أن الكثير مما تعمل معه هو منطق عرض نفسه - على سبيل المثال ، الحاجة إلى تبديل في قالب عرض مختلف. يجب أن يكون OSGI/Spring قادرًا على المساعدة ، ولكن ستحتاج إلى شيء ما في تطبيقك للاختيار بين التطبيقات المتاحة: إلى حد كبير ما تم تصميم سجل خدمة OSGI للقيام به.

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

أما بالنسبة لأسئلتك المتبقية:

هل أخترع دراجة هنا؟ هل هناك حلول قياسية لذلك؟

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

هل تعتقد أن OSGI هي التكنولوجيا المناسبة للمهمة الموصوفة؟

إذا كنت بحاجة إلى الوحدات النمطية لتكون قابلة للتبديل ، فإن اختياراتك هي OSGI وواجهة ServiceLocator أخف وزنا.

هل رسم تطبيق OSGI الخاص بي أكثر أو أقل صحة؟

لا أستطيع أن أقول حقًا دون معرفة المزيد عن مكان حدود المكون. في الوقت الحالي ، يبدو أنك قد تدفع OSGI لفعل أكثر مما هو قادر على القيام به.

لكن لا تأخذ كلامي لذلك. أنا وجدت آخر مواد القراءة في هذه الأماكن.

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

نصائح أخرى

أواجه نفس المشكلات في مشروعي الحالي. في رأيي ، يعد OSGI أفضل حل أنظف من حيث المعايير والدعم المستقبلي ، ولكن قد تضرب حاليًا بعض المشكلات إذا حاولت استخدامه في تطبيق الويب:

  1. لا يوجد حل متكامل جيدًا بين حاوية الويب ومنصة OSGI حتى الآن.
  2. قد يكون OSGI أكثر من اللازم لتطبيق ويب بناء مخصص يبحث فقط عن بنية معيارية بسيطة. أود أن أفكر في OSGI إذا كان مشروعي بحاجة إلى دعم ملحقات الطرف الثالث التي لا تكون 100 ٪ تحت سيطرتنا ، إذا كان المشروع يحتاج إلى إعادة نشر ساخنة ، وقواعد الوصول الصارمة بين الإضافات ، إلخ.

يبدو أن الحل المخصص يعتمد على لوادر فئة ومرشحات الموارد مناسب جدًا بالنسبة لي. كمثال يمكنك دراسة كود المصدر هدسون أو مشروع Java Plug-in Framework (JPF) (http://jpf.sourceforge.net/).

كما هو الحال حول تمديد web.xml ، قد نكون محظوظين مع مواصفات Servlet 3.0 (http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html# قابلية التوسيع والتحديد).

"شظية واصف نشر وحدة الويب" (المعروف أيضًا باسم web-fragment.xml) التي قدمها مواصفات Servlet 3.0 سيكون لطيفا هنا. تعرّفها المواصفات على أنها:

جزء الويب هو تقسيم منطقي لتطبيق الويب بطريقة يمكن أن تحدد الأطر المستخدمة في تطبيق الويب جميع القطع الأثرية دون مطالبة Devlopers بتحرير أو إضافة معلومات في web.xml.

Java EE 6 ربما لا يكون خيارًا لك الآن. ومع ذلك ، سيكون الحل الموحد.

Enterprise OSGI هو مجال جديد إلى حد ما ، لذا لا تعتقد أنك ستحصل على حل يلبي احتياجاتك مباشرة. ومع ذلك ، فإن أحد الأشياء التي وجدتها مفقودة من Equinox (محرك OSGI خلف Eclipse ، وبالتالي واحدة مع أكبر قاعدة مستخدمين!) هي خدمة تكوين / DI متسقة. في مشروعي مؤخرًا ، كان لدينا بعض الاحتياجات المماثلة وإنهاء بناء خدمة OSGI للتكوين البسيط.

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

بخلاف التكوين ، يمكنك إلقاء نظرة على كتاب الاعتدال الذي تم إصداره مؤخرًا للحصول على إرشادات حول استخدام OSGI كقاعدة لإنشاء تطبيقات معيارية. قد تكون الأمثلة خاصة بالاعتدال ، لكن المبادئ ستعمل مع أي إطار OSGI. نهاية لهذه الغاية - http://equinoxosgi.org/

يجب أن تنظر إلى SPRING DM Server (يتم نقله إلى Eclipse Virgo ولكن لم يتم إصداره بعد). هناك الكثير من الأشياء الجيدة في مواصفات OSGI Enterprise الأخيرة والتي تم إصدارها للتو.

أتصور أن بعض البرامج التعليمية في الربيع DM ستساعد. ولكن نعم ، من الممكن تحميل الموارد والفئات من خارج حزمة الويب باستخدام النموذج القياسي. في ذلك ، إنه مناسب.

أما بالنسبة لسياق الجلسة - يتم التعامل معها كما تتوقع في جلسة. ومع ذلك ، قد تواجه مشكلات في مشاركة هذه الجلسة بين حزم الويب إلى الحد الذي لم يكن متأكدًا مما إذا كان ذلك ممكنًا.

يمكنك أيضًا البحث عن حزمة ويب واحدة ثم استخدام سجل Eclipse Extension لتوسيع قدرات تطبيق الويب الخاص بك.

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