Rama Arjun Rama Arjun - 1 month ago 7
Java Question

Spring does not use autowired constructor for loading the bean

I have autowired

Address
bean into the constructor of
Employee
bean. And expect when getting instance of
Employee
bean I should get an instance of
Address
inside it. But Spring container is using no-args constructor of
Employee
to return the instance. Below is my code

public class Address {
public void print(){
System.out.println("inside address");
}
}

public class Employee {

private Address address;

@Autowired
public Employee(Address address){
this.address = address;
}

public Employee(){}

public Address getAddress(){
return address;
}
}

@Configuration
@ComponentScan(basePackages={"com.spring"})
public class ApplicationConfig {

@Bean
public Employee employee(){
return new Employee();
}

@Bean
public Address address(){
return new Address();
}
}

public class Main {

public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Employee employee = (Employee)context.getBean("employee");
// Here add is null !!
Address add = employee.getAddress();
}
}

Answer

The no-arg constructor is being used because that's the one that you're calling (new Employee()):

@Bean
public Employee employee() {
    return new Employee();
}

Since you're manually creating the Employee instance, rather than having Spring create it for you, you'll also have to pass in the Address yourself:

@Bean
public Employee employee() {
    return new Employee(address());
}

Note that multiple calls to address() will in fact return the same bean, rather than multiple new instances, if that was your concern.

Otherwise, the alternative is to have Employee annotated with @Component, after which Spring will automatically create the bean for you and wire in the Address dependency. You get that for free since you have component scanning turned on (assuming that Employee is in the package that you're scanning). If you go this route, you can remove the employee() bean definition from your config class, otherwise one may end up overriding the other.

Comments