fbpx

IL BLOG DEGLI RHCE ITALIANI

Applicazioni Java EE

Avatar
Claudio Sterrantino

Comparativa EJB e CDI bean

Introduzione

In questo blog post cercheremo di descrivere quelle che sono le caratteristiche delle applicazioni Java Enterprise e in particolare andremo ad approfondire i concetti legati agli Enterprise Java bean (EJB) e alla Context Dependency Injection (CDI). Prima però faremo un introduzione per approfondire alcune tematiche inerenti Java EE.

Cos’è JEE? 

Un aspetto da chiarire quando parliamo di Java Enterprise Edition è che non stiamo parlando di un linguaggio di programmazione bensì ci riferiamo ad una specifica per sviluppare applicazioni Java Enterprise, alla base di cui c’è il linguaggio Java. 

Quello che cambia è il contesto all’interno del quale andiamo ad operare. Infatti ciò che viene definito all’interno della specifica sono un insieme di API e il runtime che implementa queste API, di norma definito Application Server.

La piattaforma Java SE ci fornisce l’environment necessario per lo sviluppo di un’applicazione java: la macchina virtuale (JVM), all’interno della quale il codice viene interpretato e tradotto in linguaggio macchina, e le librerie necessarie per interfacciarsi con il sistema operativo, che ci consentono ad esempio di accedere al file system ed all’interfaccia grafica. Questo ci consente di sviluppare applicazioni standalone, tools e utility che potranno essere eseguiti da linea di comando, tramite gui o come demoni in background all’interno di processi server.

La specifica Java EE, costruita al di sopra di Java SE, mette a disposizione il runtime necessario all’esecuzione di applicazioni enterprise multi-thread, transazionali, sicure e scalabili.

Tale specifica viene definita sotto la guida del Java Community Process (JCP), un’istituzione che si occupa di promuovere l’evoluzione della piattaforma Java in collaborazione con la comunità internazionale degli sviluppatori.

Applicazioni Multi-tier

Le applicazioni Java EE sono progettate tenendo presente quella che viene definita architettura multi-tier. L’applicazione viene divisa in componenti, ognuna delle quali serve uno specifico scopo; ogni componente può essere eseguita su macchine fisiche separate. Tra i vantaggi di questo modello implementativo abbiamo:

Solitamente vengono individuati quattro livelli in un’applicazione Web Java EE:

Business Logic Tier

In questo paragrafo ci concentreremo sul core di un’applicazione Java EE, la logica di business. In particolare ci concentreremo sugli EJB e sui Managed bean, i bean iniettati tramite CDI.

Enterprise Java bean (EJB)

Un EJB è tipicamente un componente Java, cioè una classe Java che incapsula la logica di business. Diversamente dalle classi regolari Java, un EJB viene eseguito all’interno di un contesto definito EJB container.

Secondo le specifiche un EJB Container deve fornire le seguenti proprietà:

Possiamo individuare principalmente due tipi di EJB:

Session bean

Il componente Session bean è un componente di logica applicativa usato per le funzioni di business. Il termine Session, sessione, identifica il ciclo di vita del componente. il container inizializza questo componente all’inizio di una sessione utente e distruggerà il suo contenuto al termine della stessa.

Possiamo distinguere tre tipi di session bean: stateless, stateful, singleton.


Stateless

Gli Stateless Session bean sono componenti che è possibile utilizzare quando non è necessario mantenere alcuno stato nella conversazione tra il client ed il server.

Ogni volta che un client interagisce con uno Stateless ed invoca un metodo su di esso, il container preleva dal pool di Stateless Session bean un’istanza e la alloca al client. Completata la sua interazione e alla disconnessione del client, l’istanza viene deallocata e rilasciata all’interno del pool, oppure distrutta.

La gestione di questi oggetti tramite un pool pre-inizializzato comporta vantaggi in termine di risparmio di risorse. Infatti un pool sapientemente dimensionato eviterà la creazione e distruzione in memoria invece gli oggetti verranno condivisi.

Stateless life cycle

  1. Lo Stateless non esiste.
  2. Il container crea lo Stateless lo aggiunge alla bean Pool.
  3. Conseguentemente ad una CDI Injection o una JNDI CALL, il container alloca lo Stateless prendendolo dalla bean Pool. Il bean si trova dunque nello stato: Ready
  4. Il container riporta lo Stateless nella bean Pool dopo un lasso in tempo di inattività.
  5. Gli Stateless che non vengono utilizzati vengono distrutti raggiunto un timeout, dopo la rimozione del client o allo shutdown o crash del container.

Stateful

Uno Stateful Session bean è, in contrapposizione a quanto visto precedentemente, un oggetto del quale vogliamo conservare lo stato per tutta la durata dell’interazione con il client. Questo significa che se, per esempio, un particolare componente web richiede una istanza di uno Stateful più volte, esso otterrà la stessa istanza di quel particolare bean. Una ulteriore chiamata allo Stateful da parte di un client differente restituirà invece al client un’altra istanza del bean. Questo modello permette di mantenere informazioni sullo stato del bean associate al client attraverso numerose interazioni, anche con client differenti.

Stateful life cycle

  1. Lo Stateful non esiste.
  2. Il container crea il bean consecutivamente ad una CDI Injection o una JNDI CALL. Lo Stateful passa allo stato: Ready.
  3. Il container mette il bean in stato Passivated, superato un lasso in tempo in cui lo Stateful non viene utilizzato. (Lo stato Passivated indica uno stato in cui l’EJB viene mantenuto in una memoria secondari, tramite serializzazione dello stesso, in modo trasparente per il client).
  4. Un metodo dello Stateful viene invocato, il container riporta il bean allo stato: Ready.
  5. Lo Stateful viene rimosso raggiunto un timeout, dopo la rimozione del client o allo shutdown o crash del container.
  6. Lo Stateful raggiunto un timeout di inattività viene rimosso.

Singleton

Un Singleton Session bean è un bean che viene istanziato una volta per applicazione ed esiste durante tutto il ciclo di vita dell’applicazione. Ogni richiesta da parte di un client del Singleton finisce sulla stessa istanza. L’accesso concorrente al Singleton da parte di più client viene regolato dal container.

Singleton life cycle

  1. Il Singleton non è stato creato e non esiste nella memoria dell’Application Server
  2. Allo startup dell’Application Server o successivamente ad una CDI Injection una singola istanza del bean viene creata in memoria.
  3. Il Singleton viene rimosso alla rimozione dell’applicazione o allo shutdown dell’Application Server.


Message Driven bean (MDB)

Un Message Driven bean consente alle applicazioni Java Enterprise di processare messaggi in maniera asincrona. A differenza dei Session bean, dove il client chiama un metodo Java, nei MDB il client deposita un messaggio in una destinazione JMS (coda o topic). Una volta ricevuto il messaggio questo può essere consumato da un consumer, nel caso la destinazione sia una coda, o da uno o più subscriber, nel caso in cui la destinazione sia un topic. I MDB sono stateless, quindi non mantengono informazioni sullo stato della comunicazione con il client. Inoltre anche nei MDB ritroviamo il concetto di bean Pool.

Context Dependency Injection (CDI)

La Context Dependency Injection è stata introdotta nella specifica 6 di Java EE. Il concetto di Inversion Of Control (IOC), così veniva chiamata in origine la CDI, è noto da anni e veniva già utilizzato in parecchi framework. 

Attraverso CDI demandiamo a terzi, al container, il controllo dei nostri oggetti. Sarà quindi il container ad istanziare gli oggetti e tutte le loro dipendenze.

I vantaggi che derivano da questo modello implementativo sono molteplici:


CDI bean Contextual Scope

Lo scope di un CDI bean definisce quanto spesso una nuova istanza di un determinato bean deve essere creata. Come per gli EJB anche in questo caso è il container a gestire il ciclo di vita dei bean. Alcuni bean verranno creati ogni volta che un client effettua injection, altri verranno istanziati una sola volta durante il ciclo di vita dell’applicazione, altri ancora avranno un comportamento in mezzo.

Ci sono diversi scopi predefiniti out-of-the-box:

Request Scope (@RequestScoped)

Il container manterrà ogni istanza di un Request Scoped bean esclusivamente per una singola richiesta HTTP. Una volta che la richiesta è completata, l’istanza del bean sarà distrutta.

Session Scope (@SessionScoped)

Il container manterrà ogni istanza di un Session Scoped bean per ogni sessione utente. Una sessione solitamente viene considerata all’interno di più richieste in un determinato intervallo di tempo, trascorso il quale la sessione è considerata scaduta. Una volta che la sessione scade, l’istanza del bean verrà distrutta.

Conversation Scope (@ConversationScoped)

Lo scope di questo tipo di bean è ancora legato alla sessione. In questo caso però il programmatore può controllare la fine della sessione, prima della naturale terminazione. A differenza dei bean Session Scope per i bean Conversation Scope la sessione in una web application è legata ai tab del browser web.

Application Scope (@ApplicationScoped)

Il container manterrà ogni istanza di un Application Scope bean fino a quando l’applicazione non verrà rimossa o nuovamente deployata sul Application Server.

Singleton (@Singleton)

Il container manterrà una singola istanza del Singleton bean. Ogni bean che effettuerà un injection del Singleton riceverà la stessa istanza.

Client Proxy e Scopes (CDI)

Ma cosa succede in pratica quando effettuiamo l’injection di un bean? L’oggetto referenziato dal client non è il riferimento diretto all’oggetto bensì un proxy sull’oggetto stesso. Questo è vero per quasi tutti gli scope. Infatti possiamo dividere lo scope dei bean in due tipologie: 

EJB versus CDI

Arrivati a questo punto è normale chiedersi quale siano le differenze tra le due specifiche. Effettivamente esiste una sovrapposizione tra EJB e CDI bean ed è comune utilizzare entrambe le specifiche all’interno delle applicazioni JEE. Precisiamo che tutti gli EJB sono dei CDI bean, quindi possono essere iniettati tramite DI.

La specifica EJB è stata definita sopra la specifica CDI dunque offre funzionalità aggiuntive. In generale dovremmo usare gli EJB quando necessitiamo di funzionalità come: concorrenza; been pooling; security; gestione automatica delle transazioni e altre funzionalità non incluse in CDI.


Info about author
Avatar

Claudio Sterrantino

Prenota subito il tuo corso ufficiale Red Hat

GUARDA I CORSI