构造函数中的依赖注入

6
假设我有Spring服务类或JSF Bean。我在另一个类中将这些类进行了注入。到目前为止都没有什么问题,我可以在任何方法中使用这些被注入的字段。
但是,在构造函数中使用它们会导致NullPointerException异常。可能是因为构造函数在依赖注入发生之前运行,并且它看不到我的注入字段。是否有任何解决方案来在构造函数中使用依赖注入?
2个回答

5

不,您不能在构造函数中引用已注入的字段。框架必须以某种方式构造您的对象(调用构造函数),然后注入依赖项,因此它们在构造函数执行期间为空。通常的做法是将@PostConstruct注释应用于其中一个方法,并在其中执行初始化:

class MyBean {
  @Inject 
  private MyDependency myDep;

  @PostConstruct
  public void init() {
    assert myDep != null;
  }
}

如果使用Spring XML配置,您可以在<bean>定义中使用init-method="init"代替@PostConstruct。或者您可以在xml中使用构造函数注入:

<bean id="myBean" class="my.package.MyBean">
  <constructor-arg ref="myDependency/>
</bean>

或者使用注释等价物。

是的,使用 @PostConstruct 可以成为解决方案,而不是使用构造函数。 - Ahmet DAL
另外需要注意的是,@PostConstruct 注解甚至可以用于 private 的初始化方法上。将初始化方法设置为私有可见性可能有助于拥有一个干净、简洁的公共 API。(参见 http://docs.oracle.com/javaee/6/api/javax/annotation/PostConstruct.html) - Abdull

4

显然,如果该对象不存在,则无法向其注入任何内容。而要存在一个对象,必须构造一个对象。

Spring支持构造函数注入:

@Autowired
public SomeService(SomeDependency dep) {
    ...

Spring也支持@PostConstruct,它允许在所有依赖项被注入后初始化bean。

不了解JSF。


1
好的,@PostConstruct是一个EJB注释,因此在JavaEE中显然得到支持。而@Ìnject也适用于构造函数。 - Sean Patrick Floyd
@Sean:这不是EJB注释,而是Java SE API的一部分。但它确实最常与EJB结合使用。 - BalusC
@BalusC,正式来说可能是这样,但文档明确提到了EJB规范。 - Sean Patrick Floyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接