When to use javax.inject.Provider in Spring?

Tarion picture Tarion · May 8, 2013 · Viewed 42k times · Source

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?

Answer

rob picture rob · Mar 28, 2015

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