When to use javax.inject.Provider in Spring?

前端 未结 2 1676
迷失自我
迷失自我 2020-12-14 01:41

What it does is pretty simple:

@Inject
private Provider productService;

The Product service is available through

相关标签:
2条回答
  • 2020-12-14 01:55

    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

    0 讨论(0)
  • 2020-12-14 02:09

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题