Reputation: 541
I know there are 3 ways to do Dependency Injection using Spring : field, setter and constructor Injection.
But say we have more all 3 in the same Component, like so :
import base.service.FortuneService;
@Component
public class FootballCoach implements Coach {
//Field Injection
@Autowired
private FortuneService fortuneService;
//setter Injection
@Autowired
public void setFortuneService(FortuneService fortuneService) {
this.fortuneService = fortuneService;
}
//constructor Injection
@Autowired
public FootballCoach(FortuneService fortuneService) {
this.fortuneService = fortuneService;
}
}
Which one takes precedence - so to say? Will Spring just do all 3 and overwrite the fortuneService
field two times? If so, which is the last one standing? Or will only one dependency injection be chosen?
I ran the code above without problems and I got the following logs, but I don't really know how to read them.
Note: FortuneService
is an interface and I have a HappyFortuneService
class that implements it.
Sep 10, 2020 11:40:44 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry getSingleton
FINE: Creating shared instance of singleton bean 'footballCoach'
Sep 10, 2020 11:40:44 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry getSingleton
FINE: Creating shared instance of singleton bean 'happyFortuneService'
Sep 10, 2020 11:40:44 AM org.springframework.beans.factory.support.ConstructorResolver createArgumentArray
FINE: Autowiring by type from bean name 'footballCoach' via constructor to bean named 'happyFortuneService'
Sep 10, 2020 11:40:44 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry getSingleton
FINE: Creating shared instance of singleton bean 'tennisCoach'
Sep 10, 2020 11:40:44 AM org.springframework.beans.factory.support.ConstructorResolver createArgumentArray
FINE: Autowiring by type from bean name 'tennisCoach' via constructor to bean named 'happyFortuneService'
Upvotes: 5
Views: 2470
Reputation: 125252
That being said the following will happen, in order:
FortuneService
, because the object needs to be constructed first, before anything else can happen.@Autowired
with an instance of FortuneService
@Autowired
with an instance of FortuneService
Now depending on the scope of the FortuneService
, it will either inject a singleton (the default) or create a new instance (when the bean is prototype scoped).
NOTE: The ordering can be deduced from the source of the AutowiredAnnotationBeanPostProcessor
. That the constructor is called is logical but the ordering of field vs. method is coming from the buildAutowiringMetadata
method. It detects first the fields then the methods.
Upvotes: 6