Comparando JSF Beans, CDI Beans y EJB’s

por | diciembre 26, 2013

Todavía existe gran confusión acerca de los diferentes tipos de beans que proporciona Java EE 6: EJBs, CDI y los beans JSF. Este artículo intentará aclarar la diferencia entre ellos y el uso que se deberían darse.

Bean Administrados JSF, CDI y EJB’s

JSF fue desarrollado en un inicio con su propio administrador de beans y mecanismo de inyección de dependencias, el mismo que fue mejorado en la versión 2.0 de JSF al incluir anotaciones. Cuando CDI fue lanzado en Java EE 6, fue considerada como el framework para administrar beans de toda la plataforma, dejando obsoletos a los EJB’s y todos sus componentes a su alrededor.

El problema es saber cual usar y cuando usarlo, porque todos tiene el mismo proceso, empecemos con el mas sencillo y simple, los beans JSF.

Beans JSF

En pocas palabras, no los uses si estás desarrollando para Java EE 6 y usando CDI. Estos proveen un mecanismo simple para la inyección de dependencia, el trabajo de la lógica de negocio y las páginas web, pero son menos potentes que los beans CDI.

Se pueden definir usando la anotación @javax.faces.bean.ManagedBean el cual tiene un parámetro opcional name. Este nombre puede ser usado para referenciar el bean desde la página JSF.

El ámbito aplicado a los beans están definidos en el paquete javax.faces.bean el cual incluye ámbitos como: request, session, application, también tiene ámbitos  de vista(view) y personalizados(custom).

[java]
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
….
….
}
[/java]

Los beans JSF no se pueden mezclar con otro tipo de beans sin ningún tipo de codificación manual.

Beans CDI

CDI es el framework de inyección de dependencia y administración de beans, lanzado como parte del Java EE 6 que incluye una completa, integral y fácil administración de beans. Los beans CDI son mas avanzados y flexibles que los beans JSF, principalmente por los interceptores y ámbitos de conversación(conversation), eventos, decoradores y mas.

Para deployar beans CDI, hay que crear el archivo beans.xml en la carpeta META-INF del proyecto, los ámbitos de los beans CDI están definidos en el paquete  javax.enterprise.context (namely, request, conversation, session y application). Si quieres usar los beans CDI con una página JSF se la puede nombrar usando la anotación javax.inject.Named. Para inyectar un bean dentro de otro, se puede anotar una variable con la anotación javax.inject.Inject.

[java]
@Named("someBean")
@RequestScoped
public class SomeBean {

@Inject
private SomeService someService;
}
[/java]

La inyección automática como la definida anteriormente puede ser controlado a través del uso Qualifiers que pueden ayudar a conectar a la clase específica que desea inyectar.

CDI maneja la inyección en ámbitos que pueden no ser los mismos mediante el uso de proxies. Debido a esto, se puede inyectar un bean de ámbito petición dentro de un bean de ámbito de sesión y la referencia va a ser válida ante cada nueva petición, el proxy reconeta las instancias vivas de los ámbitos de los beans.

CDI también soporta eventos, interceptores, ámbitos de conversación y muchas otras características que hacen que estos sean superiores a los beans JSF.

EJBs

Los EJB’s preceden a los beans CDI y son en algunos casos muy similares y en otros casos muy distintos, las diferencias entre ellos son que los EJB’s son:

  • Transaccionales
  •  Remotos o locales
  •  Son capaces de neutralizar beans stateless(sin estado) para liberar recursos
  •  Son capaces de usar temporizadores
  •  Pueden ser asincrónicos

Los dos tipos de EJBs son llamados stateless y stateful, Los EJBs stateless pueden ser pensados como hilos seguros de un uso único sin mantener el estado entre dos peticiones. Los EJBs stateful mantienen el estado y puede ser creados y mantener su estado por un largo tiempo que sean necesarios hasta que estos sean eliminados.

Definir un EJB es simple, solo hay que anotar la clase con javax.ejb.Stateless o javax.ejb.Stateful.

Los beans Stateless debe tener un ámbito dependiente, mientras que un bean stateful puede tener cualquier ámbito.

Mientras que los beans EJBs y CDI son diferentes en términos de características, al escribir código para integrarlos son muy similares, desde los beans CDI pueden ser inyectado dentro de EJB’s y los EJB’s pueden ser inyectados dentro de beans CDI. No hay necesidad de hacer distinción cuando se inyecta el uno dentro del otro. Una vez más, los diferentes ámbitos son manejados por CDI a través de proxies. Una excepción a esto es que los CDI no tienen soporte para inyectar EJBs remotos pero estos pueden ser implementados al escribir metodos Producer.

La anotación javax.inject.Named así como cualquier Qualifier se pueden utilizar en un EJB para hacerlo coincidir con un punto de inyección.

Cuando usar estos beans

¿Cómo saber cuando usar un bean? Simple.

Nunca uses beans JSF a menos que estés trabajando con un contenedor de servlet y no quieras incorporar CDI a Tomcat(aunque exite un arquetipo Maven para esto, no hay escusas).

En general, deberias usar beans CDI a menos que necesites disponible las funcionalidades avanzadas de los EJB’s como la transaccionalidad. Puedes escribir tus propios interceptores para hacer a los beans CDI transacciones, pero por ahora, es simple usar un EJB dentro de un CDI para obtener CDI’s transaccionaes. Si estas atascado en un contenedor de servlet y estas usando CDI, entonces la única opción de transaccionalidad sin EJB es usar tus manos para escribir interceptores.

Fuente: http://www.andygibson.net/blog/article/comparing-jsf-beans-cdi-beans-and-ejbs/