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?
@PostConstruct is an annotation used on a method that needs to be executed after dependency injection is done to perform any initialization.
@PostConstruct , init-method are BeanPostProcessors. @PostConstruct is a JSR-250 annotation while init-method is Spring's way of having an initializing method. If you have a @PostConstruct method, this will be called first before the initializing methods are called.
In jdk9 @PostConstruct and @PreDestroy are in java. xml. ws. annotation which is deprecated and scheduled for removal.
Below should be possible sequence
beanb
starts to get autowiredBeanb
, beana starts to get autowired@PostConstruct
i.e. init()
of beana gets calledinit()
, System.out.println("bean a is called");
gets calledb.printMe();
gets called causing System.out.println("print me is called in Bean B");
to executebeana
completed the @PostConstruct
i.e. init()
of beanb
gets calledSystem.out.println("beanb is called");
gets calledIdeally 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.
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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With