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();
    }
}
3
  • @Autowired should be put on the "private Address address" Commented Oct 27, 2016 at 6:16
  • @FeiyuZhou but I want to inject bean through constructor. Commented Oct 27, 2016 at 6:18
  • It's not suprising since you're registering bean using @Bean annotation in your Configuration file where you are returning new Employe() using no-args constructor. Commented Oct 27, 2016 at 6:24

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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 Yeah I think that works as well, although I didn't immediately see any documentation of that.
0

@Component public class Employee{ ... }

This should work.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.