javatar
javatar

Reputation: 4621

Best Practise of injecting applicationContext in Spring3

As in the title above, I am confused about pros cons between injecting applicationContext by directly @Autowired annnotation or implementing ApplicationContextAware interface in a singleton spring bean.

Which one do you prefer in which cases and why? Thanks.

Upvotes: 14

Views: 26033

Answers (5)

herman
herman

Reputation: 12305

There is no need to use ApplicationContext at all.

ObjectFactory

If you need to use prototype scoped beans in a singleton bean, inject an org.springframework.beans.factory.ObjectFactory. For example using constructor injection:

@Service
class MyClass {
    private ObjectFactory<MyDependency> myDependencyFactory;

    public MyClass(ObjectFactory<MyDependency> prototypeFactory) {
        myDependencyFactory = prototypeFactory;
    }

}

Why

Now what's the benefit over using ApplicationContext ? You can substitute this dependency (e.g. in a test) by simply passing a lambda (since ObjectFactory is a @FunctionalInterface) that returns a stubbed version of it.

While it is possible to stub the ApplicationContext, it is not clear in that case which beans will be looked up and need to be stubbed.

Upvotes: 0

devo
devo

Reputation: 1332

If you need to get a prototype in a singleton then you can use method injection. Basically, you create an abstract method that returns the object you need and spring will return the prototype everytime you call that method. You define the "lookup-method" in your spring config. Here are some links: http://docs.spring.io/spring/docs/1.2.9/reference/beans.html#beans-factory-method-injection http://java.dzone.com/articles/method-injection-spring

Upvotes: 2

sinuhepop
sinuhepop

Reputation: 20307

As @Sean Patrick Floyd says, the need of ApplicationContext is often due to a bad design. But sometimes you have no other option. In those cases I prefer the use of @Autowired because is the way I inject all other properties. So, if I use @Autowired for injecting MyRepository, why can't I use it for ApplicationContext or any other Spring bean?

I use Spring interfaces only for those things I can't do with annotations, for example BeanNameAware.

Upvotes: 3

ManuPK
ManuPK

Reputation: 11829

Since you are not extending any of the spring classes your application is always separated from the framework. Most of the cases you will not wanted to inject the ApplicationContext as it, but will need to inject the beans defined in the ApplicationContext.

The best case is always to stick to the bare minimum, until and unless you have any specific requirement and this is very simple with spring.

So either,

  1. Annotate your beans and scan them in application context, then use @Autowire to wire them up.

  2. Use application context to wire your bean expediencies(old xml style configs). You can use @Autowire with this approach also.

When you want to control the bean life cycle, you can read the API and customize it, but most of the time these general settings will do the job.

Here are some examples.

  1. Spring Auto-Wiring Beans with @Autowired annotation
  2. Spring Auto-Wiring Beans XML Style
  3. Spring IoC container API Docs

Upvotes: 0

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298838

Actually, both are bad. Both of them tie your application to the Spring framework, thus inverting the whole inversion-of-control concept. In an ideal world, your application should not be aware of being managed by an ApplicationContext at all.

Once you have chosen to violate this principle, it doesn't really matter how you do it. ApplicationContextAware is the legacy version that has been around at least since Version 2.0. @Autowired is a newer mechanism but they work in pretty much the same way. I'd probably go with ApplicationContextAware, because it semantically makes clear what it is about.

Upvotes: 14

Related Questions