Prima di tutto lasciatemi fare alcune precisazioni:
Definizione di bean gestito : generalmente un bean gestito è un oggetto il cui ciclo di vita (costruzione, distruzione, ecc.) È gestito da un contenitore.
In Java ee abbiamo molti contenitori che gestiscono il ciclo di vita dei loro oggetti, come il contenitore JSF, il contenitore EJB, il contenitore CDI, il contenitore Servlet, ecc.
Tutti questi contenitori funzionano in modo indipendente, si avviano nell'inizializzazione del server delle applicazioni e scansionano le classi di tutti gli artefatti inclusi i file jar, ejb-jar, war e ear durante la distribuzione e raccolgono e archiviano alcuni metadati su di essi, quindi quando è necessario un oggetto di una classe in fase di esecuzione ti daranno istanze di quelle classi e dopo aver terminato il lavoro, le distruggeranno.
Quindi possiamo dire che abbiamo:
- Fagioli gestiti da JSF
- Fagioli gestiti da CDI
- Bean gestiti da EJB
- E anche i servlet sono bean gestiti perché vengono istanziati e distrutti da un contenitore, che è un contenitore servlet.
Quindi, quando vedi la parola Managed Bean, dovresti chiedere informazioni sul contesto o sul tipo di essa (JSF, CDI, EJB, ecc.)
Quindi potresti chiederti perché abbiamo molti di questi contenitori: AFAIK, i ragazzi di Java EE volevano avere un framework di iniezione delle dipendenze, ma non potevano raccogliere tutti i requisiti in una specifica perché non potevano prevedere i requisiti futuri e hanno creato EJB 1.0 e poi 2.0 e poi 3.0 e ora 3.1 ma l'obiettivo di EJB era solo per alcuni requisiti (transazione, modello di componenti distribuiti, ecc.).
Allo stesso tempo (in parallelo) si sono resi conto che dovevano supportare anche JSF, poi hanno realizzato bean gestiti da JSF e un altro contenitore per bean JSF e lo hanno considerato un contenitore DI maturo, ma ancora non era un contenitore completo e maturo.
Dopo di che Gavin King e altri bravi ragazzi;) hanno creato CDI che è il contenitore DI più maturo che abbia mai visto. CDI (ispirato a Seam2, Guice e Spring) è stato creato per colmare il divario tra JSF ed EJB e molte altre cose utili come l'iniezione di pojo, i metodi di produzione, gli intercettatori, i decoratori, l'integrazione SPI, molto flessibile, ecc. E può anche fare cosa stanno facendo i bean gestiti EJB e JSF, allora possiamo avere un solo contenitore DI maturo e potente. Ma per qualche retrocompatibilità e ragioni politiche i ragazzi di Java EE vogliono mantenerli !!!
Qui puoi trovare la differenza e i casi d'uso per ciascuno di questi tipi:
Fagioli gestiti JSF, Fagioli CDI e EJB
JSF è stato inizialmente sviluppato con il proprio meccanismo di iniezione delle dipendenze e dei bean gestiti che è stato migliorato per JSF 2.0 per includere i bean basati sull'annotazione. Quando CDI è stato rilasciato con Java EE 6, era considerato il framework bean gestito per quella piattaforma e, naturalmente, gli EJB li superavano tutti essendo in circolazione da oltre un decennio.
Il problema ovviamente è sapere quale usare e quando usarli.
Cominciamo con i bean gestiti JSF più semplici.
Fagioli gestiti JSF
In breve, non usarli se stai sviluppando per Java EE 6 e stai usando CDI. Forniscono un semplice meccanismo per l'inserimento delle dipendenze e la definizione dei bean di supporto per le pagine web, ma sono molto meno potenti dei bean CDI.
Possono essere definiti utilizzando il @javax.faces.bean.ManagedBean
annotazione che accetta un parametro name opzionale. Questo nome può essere utilizzato per fare riferimento al bean dalle pagine JSF.
L'ambito può essere applicato al bean utilizzando uno dei diversi ambiti definiti nel javax.faces.bean
pacchetto che includono la richiesta, la sessione, l'applicazione, la vista e gli ambiti personalizzati.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
I bean JSF non possono essere combinati con altri tipi di bean senza un qualche tipo di codifica manuale.
Fagioli CDI
CDI è il framework per la gestione dei bean e l'inserimento delle dipendenze rilasciato come parte di Java EE 6 e include una funzionalità bean completa e completa. I bean CDI sono molto più avanzati e flessibili dei semplici bean gestiti JSF. Possono fare uso di intercettori, ambito di conversazione, eventi, type safe injection, decoratori, stereotipi e metodi di produzione.
Per distribuire i bean CDI, è necessario posizionare un file denominato bean.xml in una cartella META-INF sul classpath. Una volta fatto questo, ogni bean nel pacchetto diventa un bean CDI. Ci sono molte funzionalità in CDI, troppe per essere trattate qui, ma come riferimento rapido per funzionalità simili a JSF, puoi definire l'ambito del bean CDI utilizzando uno degli ambiti definiti nel javax.enterprise.context
pacchetto (vale a dire, richiesta, conversazione , sessioni e ambiti dell'applicazione). Se si desidera utilizzare il bean CDI da una pagina JSF, è possibile assegnargli un nome utilizzando l' javax.inject.Named
annotazione. Per iniettare un bean in un altro bean, annotare il campo con javax.inject.Inject
annotation.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
L'iniezione automatica come quella definita sopra può essere controllata tramite l'uso di qualificatori che possono aiutare ad abbinare la classe specifica che si desidera iniettare. Se disponi di più tipi di pagamento, potresti aggiungere un qualificatore per indicare se è asincrono o meno. Sebbene sia possibile utilizzare l' @Named
annotazione come qualificatore, non dovresti in quanto è fornita per esporre i bean in EL.
CDI gestisce l'iniezione di bean con ambiti non corrispondenti tramite l'uso di proxy. Per questo motivo è possibile iniettare un bean con ambito di richiesta in un bean con ambito di sessione e il riferimento sarà ancora valido su ogni richiesta perché per ogni richiesta, il proxy si riconnette a un'istanza live del bean con ambito di richiesta.
CDI supporta anche gli intercettori, gli eventi, il nuovo ambito di conversazione e molte altre caratteristiche che lo rendono una scelta molto migliore rispetto ai bean gestiti JSF.
EJB
Gli EJB sono anteriori ai bean CDI e sono in qualche modo simili ai bean CDI e per altri versi molto diversi. In primo luogo, la differenza tra i bean CDI e gli EJB è che gli EJB sono:
- transazionale
- Remoto o locale
- Capace di passivare i bean stateful liberando risorse
- In grado di utilizzare i timer
- Può essere asincrono
I due tipi di EJB sono chiamati stateless e stateful. Gli EJB senza stato possono essere pensati come bean monouso thread-safe che non mantengono alcuno stato tra due richieste web. I bean con stato mantengono lo stato e possono essere creati e rimanere in attesa per tutto il tempo necessario fino a quando non vengono eliminati.
La definizione di un bean è semplice, basta aggiungere un'annotazione javax.ejb.Stateless
o javax.ejb.Stateful
alla classe.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
I bean senza stato devono avere un ambito dipendente mentre un bean di sessione con stato può avere qualsiasi ambito. Per impostazione predefinita, sono transazionali, ma è possibile utilizzare l'annotazione dell'attributo di transazione.
Sebbene gli EJB e i bean CDI siano molto diversi in termini di funzionalità, scrivere il codice per integrarli è molto simile poiché i bean CDI possono essere iniettati negli EJB e gli EJB possono essere iniettati nei bean CDI. Non è necessario fare alcuna distinzione quando si inietta l'uno nell'altro. Anche in questo caso, i diversi ambiti vengono gestiti da CDI tramite l'uso del proxy. Un'eccezione è che CDI non supporta l'iniezione di EJB remoti ma può essere implementata scrivendo un semplice metodo produttore per esso.
L' javax.inject.Named
annotazione e qualsiasi qualificatore possono essere utilizzati su un bean per abbinarlo a un punto di iniezione.
Quando usare quale fagiolo
Come fai a sapere quando usare quale fagiolo? Semplice.
Non utilizzare mai bean gestiti JSF a meno che non si lavori in un contenitore servlet e non si voglia provare a far funzionare CDI in Tomcat (sebbene ci siano alcuni archetipi Maven per questo, quindi non ci sono scuse).
In generale, è necessario utilizzare i bean CDI a meno che non sia necessaria la funzionalità avanzata disponibile negli EJB come le funzioni transazionali. Puoi scrivere il tuo intercettore per rendere transazionali i bean CDI, ma per ora è più semplice usare un EJB finché CDI non ottiene i bean CDI transazionali che sono proprio dietro l'angolo. Se sei bloccato in un servlet container e stai usando CDI, allora le transazioni scritte a mano o il tuo interceptor di transazione sono l'unica opzione senza EJB.
Se hai bisogno di usare @ViewScoped
in CDI dovresti
- utilizzare seam-faces o il modulo CODI di MyFaces . basta aggiungerne uno al proprio classpath e
@ViewScoped
funzionerà in CDI. MyFaces CODI ha un supporto ancora più solido di @ViewScoped
- usa i CODI di MyFaces
@ViewAccessScoped
, è un'estensione scritta su CDI da Apache, scaricala e usa l' @ViewAccessScoped
annotazione invece di @ViewScoped
.
- Usa CDI
@ConversationScoped
e rendilo di lunga durata. Vedi qui per maggiori informazioni .
- Usa l' annotazione Omnifaces @ViewScoped
Alcune parti sono state rubate da qui .