cacert
cacert

Reputation: 2797

Spring autowiring order and @PostConstruct

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?

Upvotes: 39

Views: 69884

Answers (3)

kuldeep kumar joshi
kuldeep kumar joshi

Reputation: 116

It will show class not found exception as class A depends on class B. and class B depends on class A.

Upvotes: 0

Mudassar
Mudassar

Reputation: 3205

Below should be possible sequence

  1. beanb starts to get autowired
  2. During class initialization of Beanb, beana starts to get autowired
  3. Once beana gets created the @PostConstruct i.e. init() of beana gets called
  4. Inside init(), System.out.println("bean a is called"); gets called
  5. Then b.printMe(); gets called causing System.out.println("print me is called in Bean B"); to execute
  6. Having the beana completed the @PostConstruct i.e. init() of beanb gets called
  7. 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.

Upvotes: 26

Vikrant Kashyap
Vikrant Kashyap

Reputation: 6836

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");

Upvotes: 6

Related Questions