Dovrei usare @EJB o @Inject


148

Ho trovato questa domanda: qual è la differenza tra @Inject e @EJB ma non ho ottenuto alcunché più saggio. Non ho mai eseguito Java EE né esperienza con l'iniezione di dipendenza, quindi non capisco cosa dovrei usare?

@EJB è un vecchio modo di iniettare? L'iniezione eseguita dal contenitore EJB quando si utilizza questa annotazione mentre si utilizza @Inject utilizza il nuovo framework CDI? È questa la differenza e dovrei usare @Inject invece di @EJB se questo è il caso?

Risposte:


178

La @EJBsi usa per iniettare solo EJB di ed è disponibile per un bel po 'di tempo. @Injectpuò iniettare qualsiasi bean gestito ed è parte della nuova specifica CDI (da Java EE 6).

In casi semplici puoi semplicemente passare @EJBa @Inject. In casi più avanzati (ad es. Quando dipendi fortemente dagli @EJBattributi come beanName, lookupo beanInterface) che per usarli @Injectdovresti definire un @Producercampo o un metodo.

Queste risorse potrebbero essere utili per comprendere le differenze tra @EJBe @Producese come ottenerne il meglio:

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

Documentazione di JBoss Weld:
CDI e l'ecosistema Java EE

StackOverflow:
iniettare il bean @EJB in base alle condizioni


4
perché @EJBfunziona per l'iniezione circolare (un bean singleton e un altro bean che necessitano di un riferimento reciproco)? (con riferimento alla mia risposta di seguito - non sono sicuro di fare la cosa giusta passando a @EJB)
Negromante

2
perché non stai iniettando l'implementazione, ma un proxy che si interpone sull'implementazione. per questo motivo, si ottengono i vantaggi del "late binding" e di altre funzionalità del contenitore.
lui il

33

@Injectpuò iniettare qualsiasi bean, mentre @EJBpuò solo iniettare EJB. Puoi usare entrambi per iniettare EJB, ma preferirei @Injectovunque.


1
Cosa rende esattamente l'iniezione quando usiamo @Inject? Il contenitore JavaEE? Può iniettare POJO?
Koray Tugay,

3
con CDI è il contenitore CDI (raggruppato nel contenitore JavaEE)
Bozho

16

Aggiornamento: questa risposta potrebbe essere errata o non aggiornata. Si prega di consultare i commenti per i dettagli.

Sono passato da @Injecta @EJBperché @EJBconsente l'iniezione circolare mentre @Injectvomita su di esso.

Dettagli: avevo bisogno @PostConstructdi chiamare un @Asynchronousmetodo, ma lo farebbe in modo sincrono. L'unico modo per effettuare la chiamata asincrona era fare in modo che la chiamata originale fosse un metodo di un altro bean e richiamare il metodo del bean originale. Per fare ciò, ogni fagiolo aveva bisogno di un riferimento all'altro - quindi circolare. @Injectfallito per questo compito mentre ha @EJBfunzionato.


@MartijnBurger Non ho il codice a portata di mano, né un ambiente Java EE a portata di mano. Basta creare 2 classi Java e @Injectloro nei rispettivi campi pubblici. Se funziona, allora la mia risposta è sbagliata. Se ciò non funziona, la mia risposta è corretta finora. Prossimo cambio la @Injecta @EJB(e possibilmente annotare le classi stesse? Non ricordo.). Quindi l'iniezione reciproca ciclica dovrebbe funzionare bene. Ecco perché sono passato da @Injecta @EJB. Spero che abbia senso.
Negromante

Ho creato due pojo e ho iniettato l'uno nell'altro. Funziona senza problemi nella mia configurazione (WildFly 8.2 = CDI 1.2)
Martijn Burger

1
Grazie @MartijnBurger, lo confermo e nel frattempo aggiungo una nota di cautela alla mia risposta.
Negromante,

Non sono esattamente sicuro di ciò che volevi ottenere, ma questo probabilmente fa esattamente quello che volevi e senza una dipendenza circolare. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Anche gli eventi CDI asincroni potrebbero essere un modo più pulito di procedere (a seconda dei requisiti).
JanM,

12

Ecco una buona discussione sull'argomento. Gavin King consiglia @Inject over @EJB per EJB non remoti.

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

o

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

Ri: Iniezione con @EJB o @Inject?

  1. Nov 2009, 20:48 America / New_York | Link Gavin King

Questo errore è molto strano, poiché i riferimenti locali di EJB dovrebbero sempre essere serializzabili. Bug nel glassfish, forse?

Fondamentalmente, @Inject è sempre meglio, poiché:

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

Mi sconsiglio di utilizzare @EJB ad eccezione della dichiarazione di riferimenti a bean remoti.

e

Ri: Iniezione con @EJB o @Inject?

  1. Nov 2009, 17:42 America / New_York | Link Gavin King

    Significa @EJB meglio con i bean remoti?

Per un bean remoto, non possiamo dichiarare metadati come qualificatori, @Alternative, ecc., Sulla classe bean, poiché il client semplicemente non avrà accesso a tali metadati. Inoltre, è necessario specificare alcuni metadati aggiuntivi che non sono necessari per il caso locale (nome JNDI globale di qualunque cosa). Quindi tutta quella roba deve andare altrove: vale a dire la dichiarazione di @Produces.


1
Sebbene ciò possa teoricamente rispondere alla domanda, sarebbe preferibile includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. In questo modo questa risposta sarebbe preziosa anche ora quando il collegamento è morto.
Mifeet,


4

Può anche essere utile comprendere la differenza in termini di Session Bean Identity quando si utilizza @EJB e @Inject. Secondo le specifiche il seguente codice sarà sempre true:

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

Usando @Inject invece di @EJB non c'è lo stesso.

vedere anche l' identità dei bean di sessione senza stato per ulteriori informazioni


0

L'iniezione esisteva già in Java EE 5 con le annotazioni @Resource, @PersistentUnit o @EJB, ad esempio. Ma era limitato a determinate risorse (origine dati, EJB ...) e a determinati componenti (servlet, bean, bean di supporto JSF ...). Con CDI puoi iniettare praticamente qualsiasi cosa ovunque grazie all'annotazione @Inject.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.