2012-05-10 5 views
19

In CDI è possibile definire un oggetto che vi darà gli elementi di un certo tipo, utilizzando:Qual è la molla equivalente per l'istanza del CDI, o Guices Provider

 
@Inject 
Instance<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

Allo stesso modo in Guice si può fare:

 
@Inject 
Provider<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

mi chiedo se v'è un costrutto simile in primavera, o è necessario utilizzare la ApplicationContext al fine di ottenere il riferimento?

risposta

15

Così, dopo un sacco di scavare intorno ho scoperto che la primavera supporta JSR-330. Questo JSR definisce una semplice API - l'intera specifica è letteralmente solo questa API - che standardizza diverse interfacce di dipendenze, annotazioni e comportamenti.

A differenza di Spring FactoryBean l'interfaccia javax.inject.Provider non genera eccezioni per ottenere il riferimento bean. Inoltre, avresti ancora bisogno di definire questo FactoryBean in qualche posto (leggi XML, o classe @Configuration, e questo è non ottimale).

A causa di un bug, nell'attuale Spring 3.1.1, javax.inject.Provider non funziona. Lo funziona nella primavera 3.1.0.

Per utilizzarlo è semplice necessità di includere il vaso javax.inject - se si utilizza Maven è possibile:

<dependency> 
     <groupId>javax.inject</groupId> 
     <artifactId>javax.inject</artifactId> 
     <version>1</version> 
    </dependency> 

primavera lo rileverà, e da quel momento in poi si può semplicemente:

come nell'esempio Guice, poiché è la stessa API.

Nonostante il mio precedente commento a Konstantin, Spring crea il provider da solo. (Lo stavo testando contro Spring 3.1.1 e mi imbatto in questo Spring Provider regression issue)

+0

+1 buona risposta. –

+1

Temo che ci siano differenze significative tra il provider <> e l'istanza <> (spero di sbagliarmi). Primo: Instance implementa Iterable e questo ha un grande impatto su come lo si usa. Per esempio. un uso regolare per me è dichiarare istanza @Inject xxx ... quindi potrò scorrere le istanze di ogni classe che implementa l'interfaccia senza conoscere il nome della classe. Voglio sapere come farlo usando Provider. – Rafael

+0

L'istanza <> 'non fa parte di JSR-330 e neanche parte di Spring. Il problema che avevo in quel momento era quello di ottenere i bean prototipo (che dipendono da alcune variabili di contesto) senza ottenere una sospensione sullo stesso applicationContext. –

2

suona come un FactoryBean

+0

Non proprio. Per poter eseguire l'autowire di un 'FactoryBean', è necessaria un'implementazione effettiva. Da quello che posso dire dovrei usare 'ObjectFactoryCreatingFactoryBean' ma suona troppo lavoro senza una buona ragione. –

+0

E il metodo di ricerca con scope = "prototype"? In questo modo: http://stackoverflow.com/a/10358248/1385087 –

+0

Il problema è che sembra che io debba cambiare XML (cerco di fare la maggior parte dei miei bean tramite annotazioni) per ogni istanza di "Provider". Ho notato che Spring supporta JSR-330, quindi anche l'interfaccia del Provider, tranne per il fatto che non crea questi bean al volo, è necessario crearli da soli - quindi manca completamente il punto. Inoltre non c'è annotazione del metodo di ricerca, quindi devo cambiare l'XML e creare una nuova classe per ogni bean fattorizzato? –

Problemi correlati