Search code examples
javaspringdependency-injectionspring-annotations

How the dependency class constructor is invoked before the dependent class constructor in Spring?


I have written the following code using Spring framework.

CODE

package com.spring.core.trialDI;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@ComponentScan("com.spring.core.trialDI")
class LegendConfig {

}

@Component
class A {
    public A() {
        System.out.println("I am A constructor!");
    }
}

@Component
class B {
    A a;

    public B() {
        System.out.println("I am B constructor!");
    }

    @Autowired
    public void setA(@Qualifier("a") A a) {
        System.out.println("I am setA of B!");
        this.a = a;
    }
}

@Component
class C {
    A a;

    public C() {
        System.out.println("I am C constructor!");
    }

    @Autowired
    public void setA(@Qualifier("a") A a) {
        System.out.println("I am setA of C!");
        this.a = a;
    }
}
public class TrialTheory {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(LegendConfig.class);
        B b = applicationContext.getBean(B.class);
        C c = applicationContext.getBean(C.class);
    }
}

OUTPUT

I am A constructor!
I am B constructor!
I am setA of B!
I am C constructor!
I am setA of C!

Now as in main() method, I have created a bean of B type first, so the constructor of class B must have called first even before the setter. (Constructor creates the object and its method can only be used after its creation).

But why As constructor is called before anyone? What's going on behind the scene?


Solution

  • Calling B b = applicationContext.getBean(B.class); does not mean that you create a bean (if it's a singleton bean, as in your example). It only gives you an already created bean from context. Spring creates singleton beans during its startup (during the application context creation phase).

    You can read more about how spring manages beans here: https://docs.spring.io/spring-framework/reference/core/beans.html