2014-10-07 167 views
2
@Component 
public class BeanA { 
... 
} 


@Component 
public class BeanB { 

    @Autowired 
    BeanA beanA; 

    public BeanB() { 
     // Use beanA 
     beanA.method(); 
    } 
} 

我们可以假设BeanA是在调用BeanB构造函数之前创建并初始化的吗? (我知道我们可以将BeanA作为构造函数arg传递给BeanB,这更多的是要了解spring/java初始化顺序的好奇心问题)Spring Bean:autowired属性是在构造函数之前初始化的吗?

回答

1

看看上豆http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-autowired-annotation-qualifiers

设置属性会发生后,其构造函数或工厂方法来构造。默认情况下,bean是通过名称自动装配的,值是使用setter方法设置的。所以在你的情况下,该字段将在构造函数之后设置。

这是因为

@Autowired 
BeanA beanA; 

实际上意味着要自动装配的是类实例的领域。在你的情况下beanA不是一个真正的构造函数arg。 (?嗯,这里是一个快速的问题,是编译后保留构造函数的参数名称是否有与此相关的任何调试标志?)

由于从spring documentation这个例子说,你可以申请到@Autowired构造函数和字段:

public class MovieRecommender { 

    @Autowired 
    private MovieCatalog movieCatalog; 

    private CustomerPreferenceDao customerPreferenceDao; 

    @Autowired 
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) { 
     this.customerPreferenceDao = customerPreferenceDao; 
    } 

    // ... 

} 

让我知道你是否需要任何更多的帮助。

哦,只是一个小点。你似乎在构造函数中调用beanA上的method()。如果方法可以被覆盖,这不是一个好主意。我知道这只是你在这里记下的一个例子,但只是一个小心的字眼。

1

不,那个春天很聪明,但并不那么神奇......在内部,弹簧:

  • 创建一个实例
  • 组实例的属性
  • 店最终在相关范围内的bean(exept为原型豆)和/或将其提供给呼叫者

但是创建使用了一个构造函数,并且当时它被称为属性尚未设置。

0

不,自动装配由BeanPostProcessor处理,它将在新创建的bean的构造函数之后运行。如果出于某种原因需要自动装载某些字段,然后运行一些初始化操作,则可以使用@PostConstruct注释的方法。它将在所有依赖被注入后被调用。在大多数情况下,@Autowiring构造函数(也许使对象不可变)仍然是最佳选择。