Java EE 6 @ javax.anotación.ManagedBean vs @javax.inyectar.Nombre vs @javax.cara.ManagedBean


Siento que hay un pequeño lío en la especificación Java EE 6. Hay varios conjuntos de anotaciones.

Tenemos javax.ejb anotaciones como @Stateful y @Stateless para crear EJBs.

También hay un @javax.annotation.ManagedBean para crear un bean administrado.

Hay anotaciones en javax.enterprise.context como @SessionScoped y @RequestScoped.

Lo que es más también hay @ManagedBean y @SessionScoped/@RequestScoped anotaciones en el paquete javax.faces.bean.

Y para hacer las cosas más complicadas hay un paquete javax.inject con @Named anotación.

¿Puede alguien describir cómo están relacionados unos con otros?

Dónde puedo usar @EJB, @Inject o @ManagedPropery para inyectar otros frijoles?

Author: Arjan Tijms, 2012-08-16

3 answers

En Primer lugar, permítanme hacer algunas aclaraciones:

Definición de frijol administrado : generalmente un frijol administrado es un objeto cuyo ciclo de vida (construcción, destrucción, etc.) es administrado por un contenedor.

En Java ee tenemos muchos contenedores que gestionan el ciclo de vida de sus objetos, como JSF container, EJB container, CDI container, Servlet container, etc.

Todos estos contenedores funcionan de forma independiente, arrancan en la inicialización del servidor de aplicaciones y escanee las clases de todos los artefactos, incluidos los archivos jar, ejb-jar, war y ear en tiempo de implementación y recopile y almacene algunos metadatos sobre ellos, luego cuando necesite un objeto de una clase en tiempo de ejecución, le darán instancias de esas clases y después de terminar el trabajo, las destruirán.

Así que podemos decir que tenemos:

  • JSF managed beans
  • Frijoles manejados por CDI
  • EJB frijoles manejados
  • E incluso los Servlets son frijoles manejados porque son instanciado y destruido por un contenedor, que es un contenedor servlet.

Así que cuando vea la palabra de Frijol Administrado, 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, Java EE chicos querían tener un marco de inyección de dependencias, pero no podían reunir todos los requisitos en una especificación porque no podían predecir los requisitos futuros e hicieron 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 componentes distribuidos, etc.).

Al mismo tiempo (en paralelo) se dieron cuenta de que también necesitan apoyar a JSF, luego hicieron JSF managed beans y otro contenedor para JSF beans 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 ;) hizo 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 hacer lo que EJB y JSF frijoles administrados están haciendo entonces podemos tener solo un contenedor DI maduro y poderoso. Pero por alguna compatibilidad hacia atrás y razones políticas Java EE chicos quieren mantenerlos!!!

Aquí puede encontrar la diferencia y los casos de uso para cada uno de estos tipos:

JSF Managed Beans, CDI Beans and EJBs

JSF se desarrolló inicialmente con su propio mecanismo de inyección de frijol administrado y dependencia que se mejoró para JSF 2.0 para incluir frijoles basados en anotaciones. Cuando CDI fue lanzado con Java EE 6, fue considerado como el framework bean administrado para esa plataforma y, por supuesto, EJBs los desactualizó después de haber existido durante más de una década.

El problema, por supuesto, es saber cuál usar y cuando los use.

Comencemos con los frijoles más simples, manejados por JSF.

JSF Managed Beans

En resumen, no los use si está desarrollando para Java EE 6 y usando CDI. Proporcionan un mecanismo simple para la inyección de dependencia y la definición de frijoles de respaldo para las páginas web, pero son mucho menos poderosos que los frijoles CDI.

Se pueden definir usando la anotación @javax.faces.bean.ManagedBean que toma un parámetro opcional name. Este nombre se puede utilizar para hacer referencia a la bean from JSF pages (en inglés).

El ámbito se puede aplicar al bean utilizando uno de los diferentes ámbitos definidos en el paquete javax.faces.bean que incluyen los ámbitos request, session, application, view y custom.

@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
    ....
    ....
}

Los frijoles JSF no se pueden mezclar con otros tipos de frijoles sin algún tipo de codificación manual.

Frijoles CDI

CDI es el framework de administración de frijol e inyección de dependencias que fue lanzado como parte de Java EE 6 e incluye un completo, instalación integral de frijol administrado. Los frijoles CDI son mucho más avanzados y flexibles que los simples frijoles administrados por JSF. Pueden hacer uso de interceptores, alcance de conversación, Eventos, inyección segura de tipo, decoradores, estereotipos y métodos de producción.

Para implementar frijoles CDI, debe colocar un archivo llamado frijoles.xml en una carpeta META-INF en la ruta de clase. Una vez hecho esto, cada frijol en el paquete se convierte en un frijol CDI. Hay un montón de características en CDI, demasiadas para cubrir aquí, pero como un rápido referencia para las características similares a JSF, puede definir el ámbito del frijol CDI utilizando uno de los ámbitos definidos en el paquete javax.enterprise.context (a saber, ámbitos de solicitud, conversación, sesión y aplicación). Si desea utilizar el frijol CDI de una página JSF, puede darle un nombre usando la anotación javax.inject.Named. Para inyectar un frijol en otro frijol, debe anotar el campo con 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 ayude a que coincida con la clase específica que desea inyectar. Si tiene varios tipos de pago, puede agregar un calificador para si es asíncrono o no. Si bien puede usar la anotación @Named como calificador, no debería, ya que se proporciona para exponer los frijoles en EL.

CDI maneja la inyección de frijoles con alcances no coincidentes a través del uso de proxies. Debido a esto, puede inyectar un frijol con ámbito de solicitud en un frijol 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 que lo convierte en una opción mucho mejor que JSF managed beans.

EJB

Los EJB son anteriores a los frijoles CDI y son en algunos aspectos similares a los frijoles CDI y en otros muy diferentes. Principalmente, las diferencias entre los frijoles CDI y EJBs es que EJBs son :

  • Transaccional
  • Remoto o local
  • Capaz de pasivar frijoles con estado liberando recursos
  • Capaz de hacer uso de temporizadores
  • Puede ser asíncrona

Los dos tipos de EJB se llaman stateless y stateful. EJB sin estado se puede pensar en como hilos de frijol de un solo uso seguro que no mantienen ningún estado entre dos solicitudes web. EJB con estado mantienen el estado y se pueden crear y sentarse durante el tiempo que se necesitan hasta se deshacen de ellos.

Definir un EJB es simple, simplemente agregue 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 usar la anotación del atributo transaction.

Mientras EJBs y frijoles CDI son muy diferentes en términos de características, escribir el código para integrarlos es muy similar ya que los frijoles CDI se pueden inyectar en EJBs y EJBs se pueden inyectar en frijoles CDI. No hay necesidad de hacer ninguna distinción cuando se inyecta uno en el otro. Una vez más, los diferentes ámbitos son manejados por CDI a través del uso de proxying. Una excepción a esto es que CDI no admite la inyección de EJB remotos, pero que se puede implementar escribiendo un método de productor simple para él.

La anotación javax.inject.Named así como cualquier calificador se pueden usar en un EJB para que coincida con un punto de inyección.

Cuándo usar qué frijol

¿Cómo sabes cuándo usar qué frijol? Simple.

Nunca use JSF managed beans a menos que esté trabajando en un contenedor de servlet y no quiera intentar que CDI funcione en Tomcat (aunque hay algunos arquetipos Maven para eso, por lo que no hay excusa).

En general, debe usar frijoles CDI a menos que necesite la funcionalidad avanzada disponible en los EJB, como las funciones transaccionales. Puedes escribir tu propio interceptor para hacer frijoles CDI transaccional, pero por ahora, es más simple usar un EJB hasta que el CDI obtenga frijoles CDI transaccionales que está a la vuelta de la esquina. Si está atascado en un contenedor de servlet y está utilizando CDI, entonces las transacciones escritas a mano o su propio interceptor de transacciones es la única opción sin EJBs.

Si necesita usar @ViewScoped en CDI debe

  • use seam-faceso MyFaces CODI módulo. simplemente agrega uno de ellos a tu 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 encima de CDI por Apache, solo descárguelo y use @ViewAccessScoped anotación en lugar de @ViewScoped.
  • Use CDI @ConversationScoped y hágalo de larga duración. Ver aquí para más información.
  • Use Omnifaces @ ViewScoped anotación

Algunas partes robadas de aquí.

 181
Author: Heidarzadeh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-29 20:42:59

Sí, esto puede ser confuso.

Para algunos ehm razones históricas JSF y CDI están utilizando las mismas anotaciones para los ámbitos, pero desde paquetes diferentes.

Como probablemente estás adivinando 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 de javax.ejb. Esto producirá una lista interminable de errores y anomalías sutiles.

I en general le recomendamos que hojee las primeras páginas (o incluso más) de la excelente documentación de soldadura . Esto debería ponerlo en camino para Java EE 6.

Y no dude en publicar más preguntas aquí.

 5
Author: jan groth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-18 09:13:45

Dado que no hay respuestas específicas sobre @javax.annotation.ManagedBean, aquí hay un enlace a la respuesta de una pregunta similar: Frijoles de respaldo (@ManagedBean) o Frijoles 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 estaba destinado a ser una generalización de @javax.faces.bean.ManagedBean.

De lo que he reunido, los Frijoles Administrados por JSF se están eliminando gradualmente a favor de los frijoles CDI (¿tal vez estén en desuso de JSF 2.3?), tan Supongo que @javax.annotation.ManagedBean se está volviendo más obsoleto ahora.

 1
Author: Hein Blöd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:56