【问题标题】:When to use javax.inject.Provider in Spring?什么时候在 Spring 中使用 javax.inject.Provider?
【发布时间】:2013-05-02 08:31:45
【问题描述】:

它的作用很简单:

@Inject
private Provider<ProductService> productService;

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

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

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

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

【问题讨论】:

标签: java spring dependency-injection provider


【解决方案1】:

此接口等效于org.springframework.beans.factory.ObjectFactory&lt;T&gt;,通常用于在查找原型实例时避免在客户端代码中调用BeanFactory.getBean()。通常与ObjectFactoryCreatingFactoryBean 一起使用以获取来自BeanFactory 的原型bean。

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

解决相同问题的其他选项,(使用继承而不是组合)是 lookup method injection

【讨论】:

    【解决方案2】:

    在 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();
        }
    }
    

    【讨论】:

    • 如果你通过在其中注入一些代码来支持你的答案总是好的。这很容易理解。
    • 另外它可以让你延迟加载注入的 bean。
    • 这里你用@Inject Provider&lt;Bean1&gt; bean;注入了提供者,它注入了Bean1类型的默认提供者。如果类Bean1 有多个命名bean 怎么办?你怎么说提供者返回一个特定的 Named bean?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 1970-01-01
    • 2012-07-29
    • 2012-03-13
    • 1970-01-01
    • 2021-09-05
    • 2013-08-08
    相关资源
    最近更新 更多