Backing Beans (ManagedBean) أو CDI Beans (named)؟
سؤال
لقد بدأت للتو في القراءة Core Javaserver وجوه ، الطبعة الثالثة. ويقولون هذا (التأكيد لي):
إنه حادث تاريخي أن هناك آليتان منفصلتان ، حبوب CDI والفاصوليا المدارة JSF ، للفاصوليا التي يمكن استخدامها في صفحات JSF. نقترح أن تستخدم حبوب CDI ما لم يكن يجب أن يعمل طلبك على عداء Servlet عادي مثل Tomcat.
لماذا ا؟ لا يقدمون أي التبرير. لقد كنت أستخدم @ManagedBean
لجميع الفاصوليا في تطبيق النموذج الأولي الذي يعمل على Glassfish 3 ، ولم ألاحظ حقًا أي مشاكل مع هذا. أنا لا أمانع بشكل خاص للهجرة من @ManagedBean
إلى @Named
, ، لكني أريد أن أعرف لماذا يجب أن أزعجني.
المحلول
يفضل CDI على JSF العادي لأن CDI يسمح بحقن التبعية على نطاق Javaee. يمكنك أيضًا ضخ Pojos والسماح لهم بإدارتها. مع JSF ، يمكنك فقط ضخ مجموعة فرعية مما يمكنك مع CDI.
نصائح أخرى
استخدم CDI.
حسب JSF 2.3 ، @ManagedBean
هو إهمال. أنظر أيضا العدد المواصفات 1417. هذا يعني أنه لم يعد هناك سبب للاختيار @ManagedBean
خلال @Named
. تم تنفيذ هذا لأول مرة في الإصدار التجريبي Mojarra 2.3.0 M06.
تاريخ
الفرق الأساسي هو ، @ManagedBean
يديره إطار JSF وهو فقط عبر @ManagedProperty
متاح لآخر JSF الفاصوليا المدارة. @Named
تتم إدارتها بواسطة خادم التطبيق (الحاوية) عبر إطار عمل CDI وهو عبر @Inject
متاح لأي نوع من القطع الأثرية المدارة مثل الحاوية مثل @WebListener
, @WebFilter
, @WebServlet
, @Path
, @Stateless
, ، وما إلى ذلك وحتى JSF @ManagedBean
. من الجانب الآخر ، @ManagedProperty
يفعل ليس العمل داخل أ @Named
أو أي قطعة أثرية أخرى تدار. إنه يعمل حقًا في الداخل فقط @ManagedBean
.
هناك اختلاف آخر هو أن CDI يقوم بالفعل بحقن الوكلاء الذين ينشرون إلى المثيل الحالي في نطاق الهدف على أساس لكل سلسلة/مؤشر ترابط (مثل كيفية حقن EJBs). تتيح هذه الآلية حقن حبة من نطاق أضيق في حبة من نطاق أوسع ، وهو أمر غير ممكن مع JSF @ManagedProperty
. JSF "حقن" هنا المثيل المادي مباشرة من خلال التذرع بستر (وهذا هو بالضبط السبب في أن الضابط مطلوب ، في حين أن هذا هو ليس مطلوب مع @Inject
).
في حين أن ليس من العيوب مباشرة - هناك طرق أخرى - نطاق @ManagedBean
هو ببساطة محدودة. من المنظور الآخر ، إذا كنت لا تريد فضح "الكثير" ل @Inject
, ، يمكنك أيضًا الحفاظ على حبوبك المدارة @ManagedBean
. انها مثل protected
عكس public
. لكن هذا لا يحسب حقًا.
على الأقل ، في JSF 2.0/2.1 ، فإن العيب الرئيسي لإدارة حبوب دعم JSF بواسطة CDI هو أنه لا يوجد ما يعادل CDI @ViewScoped
. ال @ConversationScoped
يقترب ، لكنه لا يزال يتطلب البدء يدويًا ويتوقف ويؤدي إلى قبيح cid
طلب المعلمة إلى عناوين URL لنتائج. MyFaces Codi يجعل الأمر أسهل عن طريق سد JSF بشفافية تمامًا javax.faces.bean.ViewScoped
إلى CDI حتى تتمكن فقط من القيام به @Named @ViewScoped
, ومع ذلك ، فإن هذا يلحق بقبيح windowId
اطلب المعلمة إلى عناوين URL للنتائج ، وأيضًا على التنقل في صفحة إلى صفحة إلى صفحة إلى صفحة. omnifaces يحل كل هذا مع CDI حقيقي @ViewScoped
الذي يربط حقًا نطاق الفول بحالة عرض JSF بدلاً من معلمة طلب تعسفي.
يقدم JSF 2.2 (الذي تم إصداره بعد 3 سنوات @ViewScoped
التعليق التوضيحي من الصندوق في نكهة javax.faces.view.ViewScoped
. JSF 2.2 حتى يأتي مع CDI فقط @FlowScoped
التي لا تحتوي على ملف @ManagedBean
ما يعادل ، مما يدفع مستخدمي JSF نحو CDI. التوقع هو ذلك @ManagedBean
وسيتم إهمال الأصدقاء وفقًا لـ Java EE 8. إذا كنت لا تزال تستخدم حاليًا @ManagedBean
, لذلك ، يوصي بشدة بالتبديل إلى CDI ليتم إعداده لمسارات الترقية المستقبلية. يتوفر CDI بسهولة في حاويات متوافقة مع Java EE على الويب ، مثل Wildfly و Tomee و Glassfish. بالنسبة إلى Tomcat ، يجب عليك تثبيته بشكل منفصل ، تمامًا كما فعلت بالفعل لـ JSF. أنظر أيضا كيفية تثبيت CDI في Tomcat؟
مع Java EE 6 و CDI لديك خيار مختلف للفاصوليا المدارة
@javax.faces.bean.ManagedBean
يشير إلى JSR 314 وتم تقديمه مع JSF 2.0. كان الهدف الرئيسي هو تجنب التكوين في ملف Faces-Config.xml لاستخدام الفول داخل صفحة JSF.@javax.annotation.ManagedBean(“myBean”)
تم تعريفه بواسطة JSR 316. يقوم بتعميم الفاصوليا المدارة JSF لاستخدامها في مكان آخر في Java EE@javax.inject.Named(“myBean”)
هي نفسها تقريبًا ، كما هو مذكور أعلاه ، باستثناء أنك تحتاج إلى ملف beans.xml في مجلد الويب/Web-Inf لتنشيط CDI.
I was using CDI in GlassFish 3.0.1, but to get it to work I had to import the Seam 3 framework (Weld). That worked pretty well.
In GlassFish 3.1 CDI stopped working, and the Seam Weld stopped working with it. I opened a bug on this but haven't seen it fixed yet. I had to convert all my code to using the javax.faces.* annotations but I plan to move back to CDI once they get it working.
I agree you should use CDI, but one issue that I haven't seen resolved yet is what to do with the @ViewScoped annotation. I have a lot of code that depends on it. It is not clear whether @ViewScoped works if you are not using @ManagedBean with it. If anyone can clarify this I would appreciate it.
أحد الأسباب الجيدة للانتقال إلى CDI: يمكن أن يكون لديك مورد شائع للجلسة (ملف تعريف المستخدم على سبيل المثال) @Inject
'ed في كل من JSF Managed Beans و Rest Services (أي Jersey/Jax-RS).
من ناحية أخرى، @ViewScoped
هو سبب مقنع للالتزام بـ JSF @ManagedBean
- خاصة لأي شيء مع أياكس كبير. لا يوجد بديل قياسي لهذا في CDI.
يبدو أنه قد يكون لديه بعض الدعم لـ @ViewScoped
-على غرار التعليقات التوضيحية لفاصوليا CDI ، لكنني لم ألعب معها شخصيًا.