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:
- Beans administrados JSF
- Frijoles administrados por CDI
- Beans gestionados por EJB
- E incluso los Servlets son beans administrados porque son instanciados y destruidos por un contenedor, que es un contenedor de servlets.
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.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
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 la javax.inject.Named
anotación. Para inyectar un frijol en otro frijol, anote el campo con una javax.inject.Inject
anotación.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
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:
- Transaccional
- Remoto o local
- Capaz de pasivar beans con estado liberando recursos
- Capaz de hacer uso de temporizadores
- Puede ser asincrónico
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
o javax.ejb.Stateful
a la clase.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
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
- utilice caras de costura o el módulo CODI de MyFaces . simplemente agregue uno de ellos a su classpath y
@ViewScoped
funcionará en CDI. MyFaces CODI tiene un soporte aún más sólido de @ViewScoped
- use MyFaces CODI's
@ViewAccessScoped
, es una extensión escrita sobre CDI por Apache, simplemente descárguela y use @ViewAccessScoped
anotación en lugar de @ViewScoped
.
- Usa CDI
@ConversationScoped
y hazlo de larga duración. Consulte aquí para obtener más información .
- Utilice la anotación Omnifaces @ViewScoped
Algunas partes robadas de aquí .