3

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();
    }
}
nbrooks
  • 18,126
  • 5
  • 54
  • 66
Rama Arjun
  • 273
  • 2
  • 3
  • 15

3 Answers3

2

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.

Community
  • 1
  • 1
nbrooks
  • 18,126
  • 5
  • 54
  • 66
  • Haven't tried it but I guess he could as well add Address argument to method signature: @Bean Employee employee(Address address) {return new Employee(address);}. – pzeszko Oct 27 '16 at 06:29
  • @pzeszko Yeah I think that works as well, although I didn't immediately see any documentation of that. – nbrooks Oct 27 '16 at 06:34
0

@Component public class Employee{ ... }

This should work.

darwinbaisa
  • 688
  • 2
  • 8
  • 13
0

If you work with spring mvc project you have to enable annotation in your applicationContext.xml you have to add this annotation <context:annotation-config> then you can use @Autowired ,if you just work with spring Ioc just add @Component on Employee and Address Classes

e2rabi
  • 4,728
  • 9
  • 42
  • 69