什么时候在 Spring 中使用 javax.inject.Provider?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16435117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use javax.inject.Provider in Spring?
提问by Tarion
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.
Product 服务可通过productService.get()
并将.get()
在每次调用时从 Spring 上下文解析实例。
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?
是否有关于 Provider 的使用的任何已知模式?
采纳答案by Jose Luis Martin
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
.
此接口等效于org.springframework.beans.factory.ObjectFactory<T>
通常用于BeanFactory.getBean()
在查找原型实例时避免调用客户端代码的接口。通常用于ObjectFactoryCreatingFactoryBean
获取由BeanFactory
.
example from ObjectFactoryCreatingFactoryBean
javadocs:
来自ObjectFactoryCreatingFactoryBean
javadoc 的示例:
<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.
使用Providers
,您可以使用ProviderCreatingFactoryBean
代替。
Other option to solve the same problem, (using inheritance instead composition) is the lookup method injection
解决相同问题的其他选项(使用继承而不是组合)是 查找方法注入
回答by rob
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.
在 cdi 中,提供者用于将范围更窄的对象注入范围更广的 bean,例如,如果会话范围的 bean 需要访问请求范围的对象,它会注入一个提供者,然后注入一个在请求中运行的方法, 调用provider.get()
以获取对适当请求范围对象的局部变量引用。
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():
下面将使用与会话中第一个请求关联的 Bean1 实例来使用 Bean2,而不管哪个请求正在调用 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:
下面将使用与当前正在调用 Bean3.doSomething() 的特定请求关联的 Bean 实例,即每个请求的不同 bean:
@SessionScoped
public class Bean3 {
@Inject Provider<Bean1> bean;
public void doSomething() {
bean.get().doSomething();
}
}