Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use javax.inject.Provider in Spring?

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.

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?

like image 723
Tarion Avatar asked May 08 '13 07:05

Tarion


People also ask

What is the use of javax inject?

Package javax. inject Description. This package specifies a means for obtaining objects in such a way as to maximize reusability, testability and maintainability compared to traditional approaches such as constructors, factories, and service locators (e.g., JNDI).

What is javax inject provider?

javax.injectProvides instances of T . Typically implemented by an injector. For any type T that can be injected, you can also inject Provider<T> . Compared to injecting T directly, injecting Provider<T> enables: retrieving multiple instances.

What is the use of @inject in Spring?

@Inject annotation is a standard annotation, which is defined in the standard "Dependency Injection for Java" (JSR-330). Spring (since the version 3.0) supports the generalized model of dependency injection which is defined in the standard JSR-330.

What is difference between @autowired and @inject?

@Inject and @Autowired both annotations are used for autowiring in your application. @Inject annotation is part of Java CDI which was introduced in Java 6, whereas @Autowire annotation is part of spring framework. Both annotations fulfill same purpose therefore, anything of these we can use in our application.


2 Answers

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();     } } 
like image 145
rob Avatar answered Oct 01 '22 03:10

rob


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

like image 37
Jose Luis Martin Avatar answered Oct 01 '22 03:10

Jose Luis Martin