2013-05-08 9 views
17

Co to robi jest dość prosta:Kiedy używać javax.inject.Provider na wiosnę?

@Inject 
private Provider<ProductService> productService; 

Usługa Produkt dostępny jest poprzez productService.get() i .get() rozwiąże wystąpienie z kontekstu Wiosna na każdym połączeniu.

Ale kiedy powinienem go użyć? I gdzie?

Moja główna użyteczność jest całkiem prosta: kiedy otrzymuję zależności cykliczne, dostawca pomaga rozwiązać zależność w czasie wykonywania. Ale wygląda to trochę losowo, jeśli rzucisz go, ale nie możesz utworzyć kontekstu spowodowanego przez okrężną zależność.

Czy są znane wzorce dotyczące korzystania z dostawców?

+0

Wygląda podobnie do Sztylet Dostawcy: http://square.github.io/dagger/ – djangofan

Odpowiedz

16

Interfejs ten jest równoważny z org.springframework.beans.factory.ObjectFactory<T>, który jest zwykle używany w celu uniknięcia wywołań BeanFactory.getBean() w kodzie klienta podczas wyszukiwania prototypów. Często używane z ObjectFactoryCreatingFactoryBean do pobierania prototypów ziaren pochodzących od BeanFactory.

przykład z 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> 

Z Providers, można użyć zamiast ProviderCreatingFactoryBean.

Inną opcją w celu rozwiązania tego samego problemu, (za pomocą spadku zamiast kompozycji) jest lookup method injection

16

W CDI dostawcy są używane do wtryskiwania przedmiotów mniejszym zakresie w większej określania zakresów ziarna, np. Jeśli komponent o ograniczonej sesji potrzebuje dostępu do obiektu o zakresie o zakresie żądania, wstrzykuje dostawcę, a następnie metodę, która działa w żądaniu, wywołuje provider.get(), aby uzyskać odwołanie do zmiennej lokalnej do odpowiedniego obiektu o zakresie żądania.

Biorąc pod uwagę następujące elementy:

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

Poniższa użyje instancji Bean1 powiązany z pierwszym wnioskiem w sesji użyć Bean2 niezależnie od żądania dzwoni Bean2.doSomething():

@SessionScoped 
public class Bean2 { 
    @Inject Bean1 bean; 

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

Następujące użyje instancji składnika bean powiązanego z konkretnym żądaniem, które aktualnie wywołuje funkcję Bean3.doSomething(), tj. Inne komponenty bean dla każdego żądania:

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

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

Zawsze jest dobrze, jeśli popierasz swoje odpowiedzi, wprowadzając w nim jakiś kod. To ułatwia zrozumienie. – NarendraSoni

+3

Plus daje to leniwy załadunek wstrzykniętego fasoli. – Tarion