Backing beans (@ManagedBean) o CDI Beans (@Named)?

Acabo de comenzar a leer a través de Core JavaServer Faces, 3rd Ed. y dicen esto (el énfasis es mío):

Es un accidente histórico que haya dos mecanismos separados, los beans CDI y los beans administrados JSF, para los beans que se pueden usar en las páginas JSF. Sugerimos que use beans CDI a menos que su aplicación deba funcionar en un corredor de servlets simple como Tomcat.

¿Por qué? Ellos no proporcionan ninguna justificación. He estado usando @ManagedBean para todos los beans en una aplicación prototipo que se ejecuta en GlassFish 3, y realmente no he notado ningún problema con esto. No me importa migrar de @ManagedBean a @Named , pero quiero saber por qué debería molestarme .

CDI es preferible a JSF simple porque CDI permite la dependency injection en todo JavaEE. También puede inyectar POJO y dejar que se administren. Con JSF solo puedes inyectar un subconjunto de lo que puedas con CDI.

Use CDI.

Según JSF 2.3, @ManagedBean está en desuso . Ver también el número de especificación 1417 . Esto significa que ya no existe una razón para elegir @ManagedBean sobre @Named . Esto se implementó por primera vez en Mojarra 2.3.0 versión beta m06.

enter image description here


Historia

La diferencia principal es que @ManagedBean es administrado por el marco JSF y solo está disponible a través de @ManagedProperty para otros beans gestionados por JSF. @Named es administrado por el servidor de aplicaciones (el contenedor) a través del marco CDI y está a través de @Inject disponible para cualquier tipo de artefacto gestionado como @WebListener , @WebFilter , @WebServlet , @Path , @Stateless , etc. e incluso un JSF @ManagedBean . Desde el otro lado, @ManagedProperty no funciona dentro de un artefacto administrado por @Named o cualquier otro contenedor. Funciona realmente solo dentro de @ManagedBean .

Otra diferencia es que CDI realmente inyecta proxies delegando a la instancia actual en el scope objective por solicitud / subproceso (como por ejemplo cómo se han inyectado los EJB). Este mecanismo permite inyectar un bean de un scope más estrecho en un bean de un scope más amplio, lo cual no es posible con JSF @ManagedProperty . JSF “inyecta” aquí la instancia física directamente invocando un setter (eso también es exactamente por qué se requiere un setter, mientras que no se requiere con @Inject ).

Si bien no es una desventaja directa, hay otras formas, el scope de @ManagedBean es simplemente limitado. Desde la otra perspectiva, si no desea exponer “demasiado” para @Inject , también puede mantener sus beans gestionados @ManagedBean . Es como protected versus public . Pero eso realmente no cuenta.

Al menos, en JSF 2.0 / 2.1, la principal desventaja de administrar beans de respaldo JSF por parte de CDI es que no hay un equivalente CDI de @ViewScoped . El @ConversationScoped se acerca, pero todavía requiere iniciarse y detenerse manualmente y agrega un feo parámetro de solicitud de cid a las URL de resultados. MyFaces CODI hace que sea más fácil al unir de forma transparente el javax.faces.bean.ViewScoped de JSF con el CDI para que pueda hacer @Named @ViewScoped , sin embargo, eso agrega un feo parámetro de solicitud de windowId a las URL de resultado, también en página simple a página navegación. OmniFaces resuelve todo esto con un verdadero CDI @ViewScoped que realmente relaciona el scope del bean con el estado de la vista JSF en lugar de con un parámetro de solicitud arbitrario.

JSF 2.2 (que se lanza 3 años después de esta pregunta / respuesta) ofrece una nueva anotación @ViewScoped completamente compatible con CDI en la caja en el estilo de javax.faces.view.ViewScoped . JSF 2.2 incluso viene con un @FlowScoped solo de @FlowScoped que no tiene un equivalente de @ManagedBean , empujando a los usuarios de JSF hacia CDI. La expectativa es que @ManagedBean y sus amigos se desaprobarán según Java EE 8. Si todavía está utilizando @ManagedBean , se recomienda encarecidamente cambiar a CDI para estar preparado para las futuras rutas de actualización. CDI está disponible en contenedores compatibles con Java Web Profile, como WildFly, TomEE y GlassFish. Para Tomcat, debe instalarlo por separado, exactamente como lo hizo para JSF. Consulte también ¿Cómo instalar CDI en Tomcat?

Con Java EE 6 y CDI tiene una opción diferente para Managed Beans

  • @javax.faces.bean.ManagedBean se refiere a JSR 314 y se introdujo con JSF 2.0. El objective principal era evitar la configuración en el archivo faces-config.xml para usar el bean dentro de una página JSF.
  • @javax.annotation.ManagedBean(“myBean”) está definido por JSR 316. Generaliza los beans administrados JSF para su uso en Java EE
  • @javax.inject.Named(“myBean”) son casi los mismos que el anterior, excepto que necesita un archivo beans.xml en la carpeta web / WEB-INF para activar CDI.

Estaba usando CDI en GlassFish 3.0.1, pero para que funcionara tuve que importar el framework Seam 3 (Weld). Eso funcionó bastante bien.

En GlassFish 3.1 CDI dejó de funcionar y Seam Weld dejó de funcionar con él. Abrí un error en esto pero todavía no lo he reparado. Tuve que convertir todo mi código para usar las anotaciones de javax.faces. *, Pero planeo volver a CDI una vez que funcionen.

Estoy de acuerdo en que debes usar CDI, pero un problema que no he visto resuelto es qué hacer con la anotación @ViewScoped. Tengo un montón de código que depende de eso. No está claro si @ViewScoped funciona si no está utilizando @ManagedBean con él. Si alguien puede aclarar esto, lo agradecería.

Una buena razón para pasar a CDI: podría tener un recurso con scope de sesión común (perfil de usuario, por ejemplo) @Inject ‘ed en frijoles administrados JSF y servicios REST (es decir, Jersey / JAX-RS).

Por otro lado, @ViewScoped es una razón de peso para seguir con JSF @ManagedBean , especialmente para cualquier cosa con AJAX significativo. No hay un reemplazo estándar para esto en CDI.

Parece que puede tener algo de apoyo para una anotación similar a @ViewScoped para los beans CDI, pero no he jugado con ella personalmente.

http://seamframework.org/Seam3/FacesModule