Introduzione
Questo tutorial mostra i diversi scopi che si possono assegnare a un Bean o a un componente in Spring Framework.
È importante capire che la definizione di un Bean è solo una ricetta per creare istanze di una classe seguendo la definizione di questa ricetta. Questa ricetta può essere poi usata una o più volte durante il ciclo di vita dell’applicazione per creare un’istanza del Bean.
Lo scope del Bean è una delle caratteristiche principali della configurazione del Bean in Spring. L’ambito indicherà quando e come verrà istanziato l’oggetto per la definizione del Bean.
Spring include 7 diversi scope Bean:
- Singleton
- Prototipo
- Richiesta
- Sessione
- Sessione globale
- Applicazione
- Websocket
Di questi, solo 5 sono disponibili in una applicazione web-aware.
Singleton
Singleton è l’ambito predefinito per un Bean, quello che sarà usato se non viene indicato altro. Questo ambito implica che il contenitore Spring creerà un’unica istanza condivisa della classe designata da questo Bean, quindi ogni volta che il Bean sarà richiesto verrà iniettato lo stesso oggetto. L’istanza di questo Bean è memorizzata in una cache gestita da Spring.
Possiamo usare le annotazioni per definire i singleton come nel seguente esempio:
Come già detto, Singleton è lo scope di default per un Spring Bean, quindi non è necessario definire il suo @Scope
(primo esempio). Tuttavia, per una migliore chiarezza e comprensione, è possibile evidenziare questo fatto utilizzando l’annotazione @Scope
come nel secondo esempio.
Il seguente test mostra il comportamento di un singleton:
Il comportamento per le classi annotate @Component
(o qualsiasi sua estensione) è lo stesso dei Bean regolari, saranno singleton a meno che non siano configurati diversamente.
Per esempio, un @RestController
come il seguente:
Assegnerà il seguente test:
Prototype
Nell’ambito Prototype, il contenitore Spring creerà una nuova istanza dell’oggetto descritto dal bean ogni volta che riceve una richiesta. Una delle regole di base indicate nella documentazione di Spring è quella di utilizzare i bean con scope Prototype quando si lavora in un ambiente in cui c’è la gestione delle sessioni (Stateful) e utilizzare lo scope Singleton quando si lavora in ambienti senza gestione delle sessioni (Stateless), tuttavia ci sono molti altri e diversi casi d’uso.
È importante sottolineare che il container Spring non si prende la responsabilità di cosa succede alle istanze degli oggetti ricevuti quando si richiede un bean. Questo significa che è compito dello sviluppatore eseguire la pulizia e liberare le risorse referenziate dall’oggetto definito dal Bean.
Come per lo scope Singleton, possiamo definire un bean con lo scope Prototype usando le annotazioni come segue::
1
2
3
4
5
|
@Bean(name = PROTOTYPE_BEAN_SAMPLE_NAME)
@Scope(SCOPE_PROTOTYPE)
public SamplePrototype() {
return new Sample();
}
|
Il prossimo test mostra il comportamento di un prototipo:
Fagioli Singleton con Prototype Beans iniettati
È molto importante sottolineare che quando si definisce un Singleton Bean con dipendenze o Prototype Beans incapsulati, l’iniezione avviene quando l’oggetto Singleton viene istanziato, quindi l’iniezione avviene solo una volta. Quindi l’oggetto iniettato definito dal Prototype Bean sarà sempre la stessa istanza anche se è stato definito con uno scope Prototype.
Per esempio, possiamo definire una classe con un Bean iniettato come segue:
Definiamo i seguenti Bean:
Il primo Bean (Sample
) ha uno scope Prototype e sarà iniettato nel secondo (SampleAutowired
) che ha uno scope Singleton. Come spiegato nei paragrafi precedenti, il comportamento atteso è che ogni volta che richiediamo un SampleAutowired
, l’istanza di Sample sarà la stessa anche quando ha uno scope Prototype perché è stata istanziata e assegnata solo una volta quando SampleAutowired
(Singleton) è stato istanziato per primo.
Questo è dimostrato nel seguente test:
Scopi di applicazioni web-aware
Come menzionato nell’introduzione, il resto degli scopi sono disponibili solo per applicazioni web-aware.
Richiesta
Il contenitore Spring creerà una nuova istanza dell’oggetto definito dal Bean ogni volta che riceve una richiesta HTTP.
Per definire un Bean con questo scope possiamo usare le seguenti annotazioni a seconda che sia un Bean o un Component:
Il comportamento del @RestController
nello snippet precedente può essere testato come segue:
Sessione
Il contenitore Spring creerà una nuova istanza dell’oggetto definito dal Bean per ciascuna delle sessioni HTTP (Stateful application) e restituirà questa stessa istanza ogni volta che riceve una richiesta all’interno della stessa sessione.
Il comportamento per il @RestController
nello snippet precedente può essere testato come segue:
Global Session
Lo scope Global Session ha un comportamento simile allo scope Session ma è applicabile solo nel contesto delle applicazioni web basate su Portlet. La specifica Portlet definisce una sessione globale come una sessione condivisa tra tutte le Portlet che compongono un’applicazione.
Se questo scope è usato in una normale applicazione web, il comportamento dei Bean definiti con questo scope sarà lo stesso che se fossero stati definiti con uno scope Session.
Application
L’ambito Application ha un comportamento molto simile all’ambito Singleton, Spring creerà una nuova istanza del bean per ogni ServletContext
. Un’applicazione Spring può avere diversi ServletContext, quindi l’istanza restituita da Spring per ogni richiesta del Bean sarà la stessa all’interno dello stesso contesto, ma diversa per ogni contesto.
Websocket
Il contenitore Spring creerà una nuova istanza dell’oggetto definito dal Bean e restituirà questa istanza per ogni richiesta prodotta nel ciclo di vita di un Websocket.
0 commenti