2012-06-08 15 views
5

Sono stato a poco a poco alle prese con Spring per un po 'di tempo e penso di avere un'idea ragionevole dei concetti, tuttavia ho trovato informazioni in un'altra delle mie discussioni che ha capovolto le cose per me ...Spring Prototype Beans and Benefits of Spring

" ... anche se i metodi di inizializzazione del ciclo di vita di callback sono chiamati tutti gli oggetti indipendentemente dal campo di applicazione, nel caso di prototipi, callback del ciclo di vita di distruzione configurato non sono chiamati. il codice cliente deve ripulire sui prototipi oggetti con scope e liberare risorse costose che i bean prototipo mantengono. Per ottenere il contenitore Spring per rilasciare le risorse detenute da bean con scope prototipo, provare a utilizzare un post-processore bean personalizzato, che contiene un riferimento ai bean che eed per essere ripulito. "

Questo mi ha fatto pensare che ho casi di utilizzo reali in cui mi piacerebbe utilizzare i fagioli prototipo in cui, ad esempio, ho bisogno di una "nuova" istanza di bean per richiesta. Tuttavia da quello che ho capito di questo frammento (dai documenti di Spring 3) Spring mantiene il riferimento ai bean che devono essere ripuliti (il riferimento stesso che significa che il bean non verrà cancellato automaticamente dal garbage collector). Inoltre, ritengo che le risorse detenute dal bean prototipo debbano essere pulite manualmente.

Qualcuno può farmi sapere se questo è corretto? Se è così c'è un tipico schema usato per affrontare questo? Apprezzerei una risposta che potesse descrivere il motivo architettonico per cui Spring implementa i fagioli prototipo in questo modo.

+1

Sul caso di necessità ambito su richiesta è possibile utente Richiesta portata;) http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference /html/ch04s04.html –

+0

@Spaeth Mi dispiace che possa essere stato fuorviante ... questa non è un'applicazione web, stavo solo cercando di dimostrare la necessità di creare una nuova istanza per gestire "qualcosa" che sta accadendo – JLove

risposta

13

La molla trattiene un riferimento ai fagioli che devono essere puliti (il riferimento stesso significa che il bean non verrà cancellato automaticamente dal garbage collector).

Sì, ma il contenitore non contiene riferimenti a bean con ambito prototipo. Questo è il motivo per cui le richiamate di distruzione non vengono chiamate: Spring crea un'istanza di bean, la collega e chiama callback di costruzione. Dà un'istanza e dimentica di quel fagiolo.

È possibile creare in modo sicuro i bean con ambito prototipo per richiesta. Spring ti darà un'istanza e nel momento in cui non hai alcun riferimento a quel bean (Spring non ne mantiene uno!), Sarà raccolto. Ma poiché Spring non sa nulla del tuo bean dopo averlo creato, non può richiamare alcuna richiamata di distruzione. In realtà questo si riduce a una domanda: perché Java non ha distruttori.

Quindi, come si puliscono i bean con scope prototipo? Bene, proprio come si pulisce qualsiasi altra risorsa in Java - esplicitamente. Fornire close(), destroy(), stop() o qualsiasi altro nome che ti piace (in considerazione l'attuazione Closeable. Si noti che tali metodi non sono in genere necessari. Garbage collector rilascerà l'intero grafo di oggetti, mentre risorse persistenti come le connessioni al database sarà chiusa quando tutta DataSource è chiuso.

+1

Grazie per voi rispondi ... questo era il modo in cui avevo creduto che funzionasse prima di leggere questo frammento, forse l'ho semplicemente interpretato male! In pratica ... continua come prima, lasciando una scia di distruzione, e tutto verrà ripulito alle mie spalle :-) – JLove

7

È letto male la documentazione dice esplicitamente:.

per ottenere il contenitore primavera per rilasciare le risorse detenute da fagioli prototipo con ambito, provare a utilizzare un post-processor di fagioli personalizzato, che contiene un riferimento alla i fagioli che devono essere c appoggiato.

Quindi Spring non ha alcun riferimento al prototipo di bean che crea. Sta a te creare un post-processore di bean che manterrà i riferimenti a questi bean, se necessario.

Inoltre, è piuttosto raro che i fagioli prototipo conservino risorse da ripulire. Ad esempio, un pool di connessioni (che deve essere distrutto correttamente all'arresto) è in genere un bean singleton. Non avrebbe molto senso renderlo un prototipo. Poiché i bean prototipo vengono spesso utilizzati per un breve periodo di tempo, il client che lo crea può rilasciare esplicitamente le sue risorse quando non lo usa più. Proprio come quando crei un nuovo stream o una connessione e la chiudi in un blocco finale.

3

Spring non ha alcuna conoscenza di tutte le istanze create utilizzando l'ambito prototipo. Semplicemente istanzia e configura i bean con scope prototipo e lo consegna al client come commentato sulla documentazione.

Primavera non gestisce l'intero ciclo di vita di un fagiolo prototipo: il contenitore istanzia, configura, decora e altrimenti assembla un oggetto prototipo, la passa al client e quindi non ha più la conoscenza di tale istanza prototipo .

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html#beans-factory-scopes-prototype