質問

What it does is pretty simple:

@Inject
private Provider<ProductService> productService;

The Product service is available through productService.get() and .get() will resolve the instance from the Spring context on each call.

But when should I use it? And where?

My main use case is pretty simple: When I get circular dependencies, the provider helps to resolve the dependency at runtime. But it looks a bit random if you throw it in just when you can't create your context caused by a circular dependency.

Are there any known patterns about the usage of Providers?

役に立ちましたか?

解決 2

This interface is equivalent to org.springframework.beans.factory.ObjectFactory<T> that is typically used to avoid BeanFactory.getBean() calls in client code when looking for prototype instances. Often used with ObjectFactoryCreatingFactoryBean to get prototypes beans sourced by the BeanFactory.

example from 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>

With Providers, you can use the ProviderCreatingFactoryBean instead.

Other option to solve the same problem, (using inheritance instead composition) is the lookup method injection

他のヒント

In cdi, Providers are used to inject objects of narrower scope into a more broadly-scoped bean, e.g., if a session-scoped bean needs access to a request scoped object it injects a provider and then a method, which is running in a request, calls provider.get() to obtain a local variable reference to the appropriate request-scoped object.

Given the following:

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

The following will use the Bean1 instance associated with the first request in the session to use Bean2 regardless of which request is calling Bean2.doSomething():

@SessionScoped
public class Bean2 {
    @Inject Bean1 bean;

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

The following will use the instance of Bean associated with the particular request that is currently calling Bean3.doSomething() i.e. a different bean for each request:

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

    public void doSomething() {
        bean.get().doSomething();
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top