bogdan.mustiata
bogdan.mustiata

Reputation: 1845

What is the Spring equivalent for CDI's Instance, or Guices Provider

In CDI you can define an object that will give you items of a certain type, using:

@Inject
Instance<MyObject> myObjectInstance;
//...
MyObject myObjectInstance.get();

Similarly in Guice you can do:

@Inject
Provider<MyObject> myObjectInstance;
//...
MyObject myObjectInstance.get();

I am wondering if there is a similar construct in Spring, or you must use the ApplicationContext in order to get the reference?

Upvotes: 22

Views: 5731

Answers (3)

iuzuz
iuzuz

Reputation: 97

Instead of using Provider you can use ObjectFactory or ObjectProvider. But:

  • For me, the Spring-own ObjectFactory has a bad name. "Factory" sounds like it creates a new object on every getObject() call. But it is not so. Also the method name is longer: getObject() vs. get().
  • The Spring-own ObjectProvider is not a functional interface. We don't use it for simplicity. It can be useful, if we need getIfUnique() or getIfAvailable(). You can use ObjectProvider if you need the methods.

See also:

Upvotes: 0

bogdan.mustiata
bogdan.mustiata

Reputation: 1845

So after a lot of digging around I found out that Spring supports JSR-330. This JSR defines a simple API - the whole spec is literally just this API - that standardizes several dependency injection interfaces, annotations and behaviors.

Unlike Spring's FactoryBean the javax.inject.Provider interface doesn't throws Exception on getting the bean reference. Furthermore, you would still need to define this FactoryBean in some place (read XML, or @Configuration class, and this is suboptimal).

Due to a bug, in current Spring 3.1.1, the javax.inject.Provider does not work. It does work in Spring 3.1.0.

In order to use it you simple need to include the javax.inject jar - if you use maven you can:

    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

Spring will detect it, and from that moment on you can simply:

@Inject
Provider<MyObject> myObjectInstance;
//...
MyObject myObjectInstance.get();

like in the Guice example, since it is the same API.

Despite my previous comment to Konstantin, Spring does create the Provider by itself. (I was testing it against Spring 3.1.1 and run into this Spring Provider regression issue)

Upvotes: 16

Konstantin V. Salikhov
Konstantin V. Salikhov

Reputation: 4653

Sounds like a FactoryBean

Upvotes: 2

Related Questions