2013-05-08 17 views
17

Che cosa è che fa è piuttosto semplice:Quando utilizzare javax.inject.Provider in primavera?

@Inject 
private Provider<ProductService> productService; 

Il servizio del prodotto è disponibile attraverso productService.get() e .get() risolverà l'istanza dal contesto della molla su ogni chiamata.

Ma quando dovrei usarlo? E dove?

Il mio caso principale è piuttosto semplice: quando ottengo delle dipendenze circolari il provider aiuta a risolvere la dipendenza in fase di esecuzione. Ma sembra un po 'casuale se lo si butta dentro solo se non è possibile creare il contesto causato da una dipendenza circolare.

Esistono modelli noti sull'utilizzo dei provider?

+0

Simile a Dagger Provider: http://square.github.io/dagger/ – djangofan

risposta

16

Questa interfaccia è equivalente a org.springframework.beans.factory.ObjectFactory<T> che viene in genere utilizzata per evitare le chiamate BeanFactory.getBean() nel codice client durante la ricerca di istanze di prototipo. Spesso utilizzato con ObjectFactoryCreatingFactoryBean per ottenere i bean dei prototipi acquistati dallo BeanFactory.

esempio da ObjectFactoryCreatingFactoryBean javadocs:

<beans> 

    <!-- Prototype bean since we have state --> 
    <bean id="myService" class="a.b.c.MyService" scope="prototype"/> 

    <bean id="myServiceFactory" 
     class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"> 
    <property name="targetBeanName"><idref local="myService"/></property> 
    </bean> 

    <bean id="clientBean" class="a.b.c.MyClientBean"> 
    <property name="myServiceFactory" ref="myServiceFactory"/> 
    </bean> 

</beans> 

Con Providers, è possibile utilizzare il ProviderCreatingFactoryBean invece.

Altre opzioni per risolvere lo stesso problema, (utilizzando l'ereditarietà invece composizione) è il lookup method injection

16

In cdi, Fornitori sono usati per iniettare oggetti di piccole entità in un bean ambito più ampio, ad es. se un bean con scope di sessione ha bisogno di accedere a un oggetto con scope di richiesta, esso inietta un provider e quindi un metodo, che è in esecuzione in una richiesta, chiama provider.get() per ottenere un riferimento di variabile locale all'oggetto ambito appropriato della richiesta.

Dato il seguente:

@RequestScoped 
public class Bean1 { 
    void doSomething(); 
} 

Di seguito utilizzerà l'istanza Bean1 associato alla prima richiesta nella sessione di utilizzare Bean2 indipendentemente da quale richiesta sta chiamando Bean2.doSomething():

@SessionScoped 
public class Bean2 { 
    @Inject Bean1 bean; 

    public void doSomething() { 
     bean.doSomething(); 
    } 
} 

Quanto segue utilizzerà l'istanza di Bean associata alla particolare richiesta che sta attualmente chiamando Bean3.doSomething(), ovvero un bean diverso per ciascuna richiesta:

@SessionScoped 
public class Bean3 { 
    @Inject Provider<Bean1> bean; 

    public void doSomething() { 
     bean.get().doSomething(); 
    } 
} 
+0

È sempre utile supportare le risposte inserendo del codice. Questo lo rende facile da capire. – NarendraSoni

+3

Inoltre ti dà il carico pigro del bean iniettato. – Tarion

Problemi correlati