何时在Spring中使用javax.inject.Provider?

时间:2013-05-08 07:34:30

标签: java spring dependency-injection provider

它做的很简单:

@Inject
private Provider<ProductService> productService;

产品服务可通过productService.get()获得,.get()将在每次调用时从Spring上下文中解析实例。

但我什么时候应该使用它?在哪里?

我的主要用例非常简单:当我获得循环依赖时,提供程序有助于在运行时解决依赖关系。但是当你无法创建由循环依赖引起的上下文时,它会看起来有点随机。

是否有关于提供商使用的已知模式?

2 个答案:

答案 0 :(得分:23)

在cdi中,提供者习惯于将范围较窄的对象注入到更广泛的bean中,例如,如果会话范围的bean需要访问请求范围的对象,它会注入提供者,然后是一个正在运行的方法在请求中,调用provider.get()以获取对适当的请求范围对象的本地变量引用。

鉴于以下内容:

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

以下将使用与会话中第一个请求关联的Bean1实例来使用Bean2,无论哪个请求正在调用Bean2.doSomething():

@SessionScoped
public class Bean2 {
    @Inject Bean1 bean;

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

以下将使用与当前正在调用Bean3.doSomething()的特定请求关联的Bean实例,即每个请求使用不同的bean:

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

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

答案 1 :(得分:18)

此接口等同于org.springframework.beans.factory.ObjectFactory<T>,通常用于在查找原型实例时避免客户端代码中的BeanFactory.getBean()调用。通常与ObjectFactoryCreatingFactoryBean一起使用来获取由BeanFactory提供的原型bean。

来自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>

使用Providers,您可以改为使用ProviderCreatingFactoryBean

解决同样问题的其他选项(使用继承代替组合)是 lookup method injection