32

它的作用非常简单:

@Inject
private Provider<ProductService> productService;

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

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

我的主要用例非常简单:当我获得循环依赖项时,提供程序会在运行时帮助解决依赖项。但是,如果您只是在由于循环依赖而无法创建上下文时将其放入,它看起来有点随机。

是否有任何关于 Providers 使用的已知模式?

4

2 回答 2

36

在 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();
    }
}
于 2015-03-28T01:13:56.380 回答
24

此接口等效于org.springframework.beans.factory.ObjectFactory<T>通常用于BeanFactory.getBean()在查找原型实例时避免调用客户端代码的接口。通常用于ObjectFactoryCreatingFactoryBean获取由BeanFactory.

来自ObjectFactoryCreatingFactoryBeanjavadocs 的示例:

<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改用 。

解决相同问题的其他选项,(使用继承而不是组合)是 查找方法注入

于 2013-05-08T08:43:49.877 回答