Siento que hay un pequeño desorden en la especificación de Java EE 6. Hay varios conjuntos de anotaciones.
Tenemos javax.ejb
anotaciones como @Stateful
y @Stateless
para crear EJB.
También existe la posibilidad @javax.annotation.ManagedBean
de crear un bean administrado.
Hay anotaciones en me javax.enterprise.context
gusta @SessionScoped
y @RequestScoped
.
Además, también hay @ManagedBean
y @SessionScoped
/ @RequestScoped
anotaciones en el javax.faces.bean
paquete.
Y para hacer las cosas más complicadas, hay un paquete javax.inject
con @Named
anotación.
¿Alguien puede describir cómo se relacionan entre sí?
¿Dónde puedo usar @EJB
, @Inject
o @ManagedPropery
para inyectar otros granos?
java
jakarta-ee
java-ee-6
cdi
Piotr Gwiazda
fuente
fuente
Respuestas:
Antes que nada déjame hacer algunas aclaraciones:
Definición de bean gestionado : generalmente un bean gestionado es un objeto cuyo ciclo de vida (construcción, destrucción, etc.) es gestionado por un contenedor.
En Java ee tenemos muchos contenedores que gestionan el ciclo de vida de sus objetos, como contenedor JSF, contenedor EJB, contenedor CDI, contenedor Servlet, etc.
Todos estos contenedores funcionan de manera independiente, se inician en la inicialización del servidor de aplicaciones y escanean las clases de todos los artefactos, incluidos los archivos jar, ejb-jar, war y ear en el tiempo de implementación y recopilan y almacenan algunos metadatos sobre ellos, luego, cuando se necesita un objeto de una clase en tiempo de ejecución te darán instancias de esas clases y después de terminar el trabajo, las destruirán.
Entonces podemos decir que tenemos:
Entonces, cuando vea la palabra Managed Bean, debe preguntar sobre el contexto o el tipo de la misma (JSF, CDI, EJB, etc.)
Entonces podría preguntarse por qué tenemos muchos de estos contenedores: AFAIK, los chicos de Java EE querían tener un marco de inyección de dependencia, pero no pudieron reunir todos los requisitos en una especificación porque no podían predecir los requisitos futuros y crearon EJB 1.0 y luego 2.0 y luego 3.0 y ahora 3.1, pero el objetivo de EJB era solo para algunos requisitos (transacción, modelo de componente distribuido, etc.).
Al mismo tiempo (en paralelo) se dieron cuenta de que también necesitaban admitir JSF, luego hicieron beans administrados por JSF y otro contenedor para beans JSF y lo consideraron un contenedor DI maduro, pero aún no era un contenedor completo y maduro.
Después de eso, Gavin King y algunos otros chicos agradables;) hicieron CDI, que es el contenedor DI más maduro que he visto. CDI (inspirado en Seam2, Guice y Spring) se hizo para llenar el vacío entre JSF y EJB y muchas otras cosas útiles como inyección de pojo, métodos de producción, interceptores, decoradores, integración SPI, muy flexible, etc. e incluso puede hacerlo qué están haciendo los beans administrados por EJB y JSF, entonces podemos tener solo un contenedor DI maduro y poderoso. ¡Pero por alguna compatibilidad con versiones anteriores y razones políticas, los chicos de Java EE quieren mantenerlos!
Aquí puede encontrar la diferencia y los casos de uso para cada uno de estos tipos:
Beans administrados JSF, Beans CDI y EJB
JSF se desarrolló inicialmente con su propio bean administrado y un mecanismo de inyección de dependencia que se mejoró para JSF 2.0 para incluir beans basados en anotaciones. Cuando se lanzó CDI con Java EE 6, se consideró como el marco de bean administrado para esa plataforma y, por supuesto, los EJB los desactualizaron todos después de haber existido durante más de una década.
El problema, por supuesto, es saber cuál usar y cuándo usarlos.
Comencemos con los beans administrados JSF más simples.
Beans administrados JSF
En resumen, no los use si está desarrollando para Java EE 6 y usando CDI. Proporcionan un mecanismo simple para la inyección de dependencias y la definición de beans de respaldo para páginas web, pero son mucho menos poderosos que los beans CDI.
Se pueden definir usando la
@javax.faces.bean.ManagedBean
anotación que toma un parámetro de nombre opcional. Este nombre se puede utilizar para hacer referencia al bean desde páginas JSF.El alcance se puede aplicar al bean utilizando uno de los diferentes alcances definidos en el
javax.faces.bean
paquete que incluyen la solicitud, sesión, aplicación, vista y alcances personalizados.Los beans JSF no se pueden mezclar con otros tipos de beans sin algún tipo de codificación manual.
Frijoles CDI
CDI es el marco de administración de beans e inyección de dependencias que se lanzó como parte de Java EE 6 e incluye una instalación de bean administrada completa e integral. Los beans CDI son mucho más avanzados y flexibles que los beans administrados por JSF simples. Pueden hacer uso de interceptores, alcance de conversación, eventos, inyección segura de tipos, decoradores, estereotipos y métodos de producción.
Para implementar beans CDI, debe colocar un archivo llamado beans.xml en una carpeta META-INF en la ruta de clases. Una vez que haga esto, cada bean del paquete se convierte en un bean CDI. Hay muchas características en CDI, demasiadas para cubrir aquí, pero como referencia rápida para características similares a JSF, puede definir el alcance del bean CDI usando uno de los alcances definidos en el
javax.enterprise.context
paquete (es decir, solicitud, conversación , ámbitos de sesión y aplicación). Si desea utilizar el bean CDI de una página JSF, puede darle un nombre usando lajavax.inject.Named
anotación. Para inyectar un frijol en otro frijol, anote el campo con unajavax.inject.Inject
anotación.La inyección automática como la definida anteriormente se puede controlar mediante el uso de calificadores que pueden ayudar a que coincida con la clase específica que desea inyectar. Si tiene varios tipos de pago, puede agregar un calificador para determinar si es asíncrono o no. Si bien puede usar la
@Named
anotación como calificador, no debería hacerlo, ya que se proporciona para exponer los beans en EL.CDI maneja la inyección de beans con alcances no coincidentes mediante el uso de proxies. Debido a esto, puede inyectar un bean con ámbito de solicitud en un bean con ámbito de sesión y la referencia seguirá siendo válida en cada solicitud porque para cada solicitud, el proxy se vuelve a conectar a una instancia en vivo del bean con ámbito de solicitud.
CDI también tiene soporte para interceptores, eventos, el nuevo alcance de conversación y muchas otras características, lo que lo convierte en una opción mucho mejor que los beans administrados por JSF.
EJB
Los EJB son anteriores a los beans CDI y de alguna manera son similares a los beans CDI y, en otros aspectos, muy diferentes. Principalmente, las diferencias entre los beans CDI y los EJB es que los EJB son:
Los dos tipos de EJB se denominan sin estado y con estado. Los EJB sin estado pueden considerarse beans de un solo uso seguros para subprocesos que no mantienen ningún estado entre dos solicitudes web. Los EJB con estado mantienen el estado y se pueden crear y permanecer durante el tiempo que sean necesarios hasta que se eliminen.
Definir un EJB es simple, simplemente agrega una anotación
javax.ejb.Stateless
ojavax.ejb.Stateful
a la clase.Los beans sin estado deben tener un ámbito dependiente, mientras que un bean de sesión con estado puede tener cualquier ámbito. De forma predeterminada, son transaccionales, pero puede utilizar la anotación de atributo de transacción.
Si bien los beans EJB y CDI son muy diferentes en términos de características, escribir el código para integrarlos es muy similar, ya que los beans CDI se pueden inyectar en EJB y los EJB se pueden inyectar en beans CDI. No es necesario hacer ninguna distinción al inyectar uno en el otro. Nuevamente, CDI maneja los diferentes ámbitos mediante el uso de proxy. Una excepción a esto es que CDI no admite la inyección de EJB remotos, pero eso se puede implementar escribiendo un método de productor simple para él.
javax.inject.Named
Tanto la anotación como los calificadores se pueden utilizar en un EJB para hacer coincidir con un punto de inyección.Cuando usar que frijol
¿Cómo saber cuándo usar qué frijol? Sencillo.
Nunca use beans administrados por JSF a menos que esté trabajando en un contenedor de servlet y no quiera intentar que CDI funcione en Tomcat (aunque hay algunos arquetipos de Maven para eso, así que no hay excusa).
En general, debe utilizar beans CDI a menos que necesite la funcionalidad avanzada disponible en los EJB, como las funciones transaccionales. Puede escribir su propio interceptor para hacer que los beans CDI sean transaccionales, pero por ahora, es más sencillo usar un EJB hasta que CDI obtenga beans CDI transaccionales que están a la vuelta de la esquina. Si está atascado en un contenedor de servlets y está utilizando CDI, las transacciones escritas a mano o su propio interceptor de transacciones es la única opción sin EJB.
Si necesita usarlo
@ViewScoped
en CDI, debe@ViewScoped
funcionará en CDI. MyFaces CODI tiene un soporte aún más sólido de @ViewScoped@ViewAccessScoped
, es una extensión escrita sobre CDI por Apache, simplemente descárguela y use@ViewAccessScoped
anotación en lugar de@ViewScoped
.@ConversationScoped
y hazlo de larga duración. Consulte aquí para obtener más información .Algunas partes robadas de aquí .
fuente
@ManagedProperty("#{someBean})"
forma correcta?@Named
y@javax.enterprise.context.RequestScoped
y use la inyección CDI usando la anotación @Inject. no use beans administrados por jsf si no es necesario;).Sí, esto puede resultar confuso.
Por algunas razones históricas de ehm , JSF y CDI están usando las mismas anotaciones para los ámbitos, pero de diferentes paquetes.
Como probablemente adivine, los de
javax.faces.bean
son de la especificación JSF y no están relacionados con CDI. No los use a menos que tenga una muy buena razón para hacerlo. Y nunca los mezcle con anotaciones CDI dejavax.ejb
. Esto producirá una lista infinita de errores y anomalías sutiles.Por lo general, le recomiendo que hojee las primeras páginas (o incluso más) de la excelente documentación de Weld . Esto debería encaminarlo hacia Java EE 6.
Y no dude en publicar más preguntas aquí.
fuente
@javax.annotation.ManagedBean
es inútil ya que CDI trata todas las clases como beans administrados, ¿verdad?Dado que no hay respuestas específicas sobre
@javax.annotation.ManagedBean
, aquí hay un enlace a la respuesta de una pregunta similar: ¿ Beans de respaldo (@ManagedBean) o Beans CDI (@Named)? . La especificación se puede encontrar en http://download.oracle.com/otndocs/jcp/managed_beans-1.0-fr-eval-oth-JSpec/ . Así que me parece que@javax.annotation.ManagedBean
se suponía que era una generalización de@javax.faces.bean.ManagedBean
.Por lo que reuní, JSF Managed Beans se está eliminando gradualmente a favor de CDI Beans (¿tal vez quedando obsoleto de JSF 2.3?), Por lo que supongo que ahora se
@javax.annotation.ManagedBean
está volviendo más obsoleto.fuente
@Named
reemplazará@ManagedBean
en el futuro?@Named
beans CDI reemplazarán a JSF@ManagedBeans
, por ejemplo, en stackoverflow.com/questions/4347374/… , BalusC dice "La expectativa es que @ManagedBean y sus amigos quedarán obsoletos según Java EE 8. ".