Reputation: 7042
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
Reputation: 1
in your code snippets
in first approach is completely fine and that's they standard way to get that object.
in second approach i am not sure but probably you will get error bcoz you are not
overriding setApplicationContext()
method.
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
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