问题
I have a question about auto-wiring order and @PostConstruct logic in Spring. For example following demo code I have a main Spring Boot class:
@SpringBootApplication
public class Demo1Application {
@Autowired
BeanB beanb;
public static void main(String[] args) {
SpringApplication.run(Demo1Application.class, args);
}
}
and 2 @Service Definitions:
@Service
public class BeanB {
@Autowired
private BeanA beana ;
@PostConstruct
public void init(){
System.out.println("beanb is called");
}
public void printMe(){
System.out.println("print me is called in Bean B");
}
}
@Service
public class BeanA {
@Autowired
private BeanB b;
@PostConstruct
public void init(){
System.out.println("bean a is called");
b.printMe();
}
}
and I have the following output:
bean a is called
print me is called in Bean B
beanb is called
My question is how autowiring takes place step by step like a scenario above?
And how printMe() method of beanb is called without calling its @PostConstruct first?
回答1:
Below should be possible sequence
beanbstarts to get autowired- During class initialization of
Beanb, beana starts to get autowired - Once beana gets created the
@PostConstructi.e.init()of beana gets called - Inside
init(),System.out.println("bean a is called");gets called - Then
b.printMe();gets called causingSystem.out.println("print me is called in Bean B");to execute - Having the
beanacompleted the@PostConstructi.e.init()ofbeanbgets called - Then
System.out.println("beanb is called");gets called
Ideally the same can be better observed by a debugger in eclipse.
The Spring reference manual explains how circular dependencies are resolved. The beans are instantiated first, then injected into each other.
回答2:
Your Answer is Correct as you shown in Your question.
Now Getting the concept of Notation @Autowired. All @Autowired Objects are initialized and loaded in memory just after class Loading is done.
Now here is your SpringBootApplication
@SpringBootApplication
public class Demo1Application {
@Autowired
BeanB beanb; // You are trying to autowire a Bean class Named BeanB.
Here at above Console Application that you have write try to autowire and inject a object of type BeanB.
Now here is your definition of BeanB
@Service
public class BeanB {
@Autowired
private BeanA beana ;
In BeanB class you are trying to inject the Object of Class BeanA which is also defined in your console Project.
So, In Your Demo1Application to inject a Object of Class BeanB there must need to inject a Object of class BeanA.
Now BeanA Class Object is Created First.
Now if you see the definition of Your Class BeanA
@Service
public class BeanA {
@Autowired
private BeanB b;
@PostConstruct // after Creating bean init() will be execute.
public void init(){
System.out.println("bean a is called");
b.printMe();
}
}
So, After injecting the Object BeanA method bind with @PostContruct annotation is going to execute.
So, execution flow will be..
System.out.println("bean a is called");
System.out.println("print me is called in Bean B");
System.out.println("beanb is called");
来源:https://stackoverflow.com/questions/38068303/spring-autowiring-order-and-postconstruct