Aivar
Aivar

Reputation: 7042

What's the benefit of Spring *Aware interfaces vs. injecting required objects?

Spring has various *Aware-interfaces, eg. ApplicationContextAware which add a setter to the implementer. Does using these interfaces have any benefits over simply requesting the dependency via regular DI means (eg. constructor injection).

In other words, when should I prefer

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

over

@Service
class MyService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    public MyService(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}

or

@Service
class MyService implements ApplicationContextAware {
    @Autowired
    private ApplicationContext applicationContext;
}

?

Upvotes: 2

Views: 2705

Answers (2)

Shaikh Aejaz
Shaikh Aejaz

Reputation: 1

in your code snippets

  1. in first approach is completely fine and that's they standard way to get that object.

  2. in second approach i am not sure but probably you will get error bcoz you are not overriding setApplicationContext() method.

  3. last but not least in third approach you will get error bcoz you are not overriding setApplicationContext() method.

    if we override setApplicationContext() in third snippet then IOC Container first inject null bcoz @Autowired cannot inject ApplicationContext object

    [Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.springframework.context.ApplicationContext.getBean(String, java.lang.Class)" because "this.ctx" is null]

    then overriden setApplicationContext() executes and it will inject ApplicationContext object in the say way as approach 1. so 1 and 3 are same

CONCLUSION :: to inject spring supplied special propeties/object like ApplicationContext object we must implement ApplicationContextAware interfact (XxxAware interface for respective properties/object)

Upvotes: 0

Paweł Wyrwiński
Paweł Wyrwiński

Reputation: 1443

All 3 examples have the same effect. There are just some nuances, and in the end it's a matter of style.

In the first example - Spring scans for components implementing certain marker interfaces, ApplicationContextAware is one of them, and executes method of the interface with actual applicationContext instance provided in the parameter by the DI runtime.

Second example works only in Spring 4.3 and higher. When your bean has single constructor that specifies its dependencies, then dependency injection by constructor is assumed even without annotations.

Third one is just plain injection by @Autowired annotation.

There is no simple answer to which way is better. Documentation for ApplicationContextAware interface even suggests that you might be better with other ways if you need applicationContext just for bean lookup (e.g. when you have to use method injection technique).

To sum it up: the choice between 1st, 2nd and 3rd is just a choice between different IoC/DI flavour and also if to skip an optional @Autowired annotation or not.

P.S.
your 2nd and 3rd examples do not have to implement ApplicationContextAware interface at all. In fact the compiler will complain that you are not providing the setter for ApplicationContect object.

Upvotes: 7

Related Questions