¿Debo usar @EJB o @Inject

148

He encontrado esta pregunta: ¿Cuál es la diferencia entre @Inject y @EJB pero no entendí nada mejor? No he hecho Java EE antes ni tengo experiencia con la inyección de dependencia, así que no entiendo qué debo usar.

¿Es @EJB una antigua forma de inyectar? ¿La inyección la realiza el contenedor EJB cuando usa esta anotación mientras usa @Inject usa el nuevo marco CDI? ¿Es esa la diferencia y debería usar @Inject en lugar de @EJB si este es el caso?

LuckyLuke
fuente

Respuestas:

178

El @EJBse usa para inyectar solo EJB y está disponible desde hace bastante tiempo. @Injectpuede inyectar cualquier bean administrado y es parte de la nueva especificación CDI (desde Java EE 6).

En casos simples, simplemente puede cambiar @EJBa @Inject. En casos más avanzados (p. Ej., Cuando depende en gran medida de @EJBlos atributos como beanName, lookupo beanInterface) que para usarlo @Inject, necesitaría definir un @Producercampo o método.

Estos recursos podrían ser útiles para entender las diferencias entre @EJBy @Producesy cómo obtener lo mejor de ellos:

Blog de Antonio Goncalves:
CDI Parte I
CDI Parte II
CDI Parte III

Documentación de JBoss Weld:
CDI y el ecosistema Java EE

StackOverflow:
inyecta el bean @EJB según las condiciones

Piotr Nowicki
fuente
44
¿por qué @EJBfunciona para inyección circular (un bean singleton y otro bean que necesitan una referencia entre ellos)? (con referencia a mi respuesta a continuación, no estoy seguro de si estoy haciendo lo correcto al cambiar a @EJB)
nigromante
2
porque no estás inyectando la implementación, sino un proxy que se interpone en la implementación. debido a esto, obtiene las ventajas de "enlace tardío" y otras características del contenedor.
él
33

@Injectpuede inyectar cualquier bean, mientras @EJBque solo puede inyectar EJB. Puede usar cualquiera para inyectar EJB, pero prefiero en @Injecttodas partes.

Bozho
fuente
1
¿Qué hace exactamente la inyección cuando usamos @Inject? El contenedor JavaEE? ¿Se puede inyectar POJO 's?
Koray Tugay
3
con CDI es el contenedor CDI (incluido en el contenedor JavaEE)
Bozho
16

Actualización: esta respuesta puede ser incorrecta o desactualizada. Por favor, vea los comentarios para más detalles.

Cambié de @Injecta @EJBporque @EJBpermite la inyección circular mientras @Injectvomita.

Detalles: necesitaba @PostConstructllamar a un @Asynchronousmétodo, pero lo haría sincrónicamente. La única forma de hacer la llamada asincrónica era hacer que la llamada original fuera un método de otro bean y que volviera a llamar al método del bean original. Para hacer esto, cada bean necesitaba una referencia al otro, por lo tanto circular. @Injectfalló para esta tarea mientras @EJBtrabajaba.

nigromante
fuente
@MartijnBurger No tengo el código a mano, ni un entorno Java EE a mano. Simplemente cree 2 clases Java y @Injectcolóquelas en los campos públicos del otro. Si eso funciona, entonces mi respuesta es incorrecta. Si eso no funciona, entonces mi respuesta es correcta hasta ahora. A continuación, cambie el @Injecta @EJB(y posiblemente anotar las clases ellos mismos? Lo olvido). Entonces la inyección mutua cíclica debería funcionar bien. Es por eso que cambié de @Injecta @EJB. Espero que esto tenga sentido.
nigromante
Creé dos pojo's e inyecté los pojo uno dentro del otro. Funciona sin problemas en mi configuración (WildFly 8.2 = CDI 1.2)
Martijn Burger
1
Gracias @MartijnBurger, lo confirmaré y, mientras tanto, agregaré una nota de precaución a mi respuesta.
nigromante
No estoy seguro de lo que quería lograr, pero esto probablemente hace exactamente lo que quería y sin una dependencia circular. tomee.apache.org/examples-trunk/async-postconstruct/README.html . También los eventos CDI asíncronos podrían ser una forma más limpia de hacerlo (según los requisitos).
JanM
12

Aquí hay una buena discusión sobre el tema. Gavin King recomienda @Inject sobre @EJB para EJB no remotos.

http://www.seamframework.org/107780.lace

o

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Re: ¿Inyectando con @EJB o @Inject?

  1. Nov 2009, 20:48 América / Nueva_York | Link Gavin King

Ese error es muy extraño, ya que las referencias locales EJB siempre deben ser serializables. ¿Insecto en pez de cristal, tal vez?

Básicamente, @Inject siempre es mejor, ya que:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

Recomiendo contra el uso de @EJB, excepto para declarar referencias a EJB remotos.

y

Re: ¿Inyectando con @EJB o @Inject?

  1. Noviembre de 2009, 17:42 América / Nueva_York | Link Gavin King

    ¿Significa @EJB mejor con EJB remotos?

Para un EJB remoto, no podemos declarar metadatos como calificadores, @Alternative, etc., en la clase bean, ya que el cliente simplemente no tendrá acceso a esos metadatos. Además, se deben especificar algunos metadatos adicionales que no necesitamos para el caso local (nombre JNDI global de lo que sea). Por lo tanto, todo eso debe ir a otro lugar: la declaración @Produces.

John Manko
fuente
1
Si bien esto puede responder teóricamente la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace para referencia. De esta manera, esta respuesta sería valiosa incluso ahora cuando el enlace está muerto.
Mifeet
4

También puede ser útil comprender la diferencia en términos de Identidad de bean de sesión cuando se usa @EJB y @Inject. Según las especificaciones, el siguiente código siempre será true:

@EJB Cart cart1;
@EJB Cart cart2;
 if (cart1.equals(cart2)) { // this test must return true ...}

Usar @Inject en lugar de @EJB no es lo mismo.

vea también identidad de beans de sesión sin estado para más información

conocido
fuente
0

La inyección ya existía en Java EE 5 con las anotaciones @Resource, @PersistentUnit o @EJB, por ejemplo. Pero estaba limitado a ciertos recursos (fuente de datos, EJB...) Y a ciertos componentes (Servlets, EJBs, JSF backing bean...). Con CDI puede inyectar casi cualquier cosa en cualquier lugar gracias a la anotación @Inject.

javierZanetti
fuente