Spring不使用自动连接的构造函数来加载bean



我已将Address bean自动连接到Employee bean的构造函数中。期望当得到Employee bean的实例时,我应该在它里面得到Address的实例。但是Spring容器使用Employee的无参数构造函数来返回实例。下面是我的代码

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();
    }
}

正在使用无参数构造函数,因为这是您正在调用的(new Employee()):

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

由于您是手动创建Employee实例,而不是让Spring为您创建它,因此您还必须自己传入Address:

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

注意,对address()的多次调用实际上将返回相同的bean,而不是多个新实例,如果这是您关心的。

否则,另一种选择是用@Component注释Employee,之后Spring将自动为您创建bean并连接到Address依赖项。这是免费的,因为您已经打开了组件扫描(假设Employee在您正在扫描的包中)。如果您走这条路,您可以从配置类中删除employee() bean定义,否则一个bean可能最终覆盖另一个bean。

@Component public class Employee{ ... }

如果您使用spring mvc项目,您必须在applicationContext.xml中启用注释,您必须添加此注释<context:annotation-config>,然后您可以使用@Autowired,如果您只是使用spring Ioc,只需添加@Component on EmployeeAddress Classes

最新更新