Java @当在另一个bean的构造函数中引用时,autowiredbean为null

Java @当在另一个bean的构造函数中引用时,autowiredbean为null,java,spring,autowired,Java,Spring,Autowired,下面显示的是一段代码,我试图在其中引用ApplicationProperties bean。当我从构造函数引用它时,它是空的,但是当从另一个方法引用它时,它是好的。到目前为止,我在其他类中使用这个自连线bean还没有问题。但这是我第一次尝试在另一个类的构造函数中使用它 在下面的代码段中,从构造函数调用applicationProperties时为null,但在convert方法中引用时为null。我错过了什么 @Component public class DocumentManager imp

下面显示的是一段代码,我试图在其中引用ApplicationProperties bean。当我从构造函数引用它时,它是空的,但是当从另一个方法引用它时,它是好的。到目前为止,我在其他类中使用这个自连线bean还没有问题。但这是我第一次尝试在另一个类的构造函数中使用它

在下面的代码段中,从构造函数调用applicationProperties时为null,但在convert方法中引用时为null。我错过了什么

@Component
public class DocumentManager implements IDocumentManager {

  private Log logger = LogFactory.getLog(this.getClass());
  private OfficeManager officeManager = null;
  private ConverterService converterService = null;

  @Autowired
  private IApplicationProperties applicationProperties;


  // If I try and use the Autowired applicationProperties bean in the constructor
  // it is null ?

  public DocumentManager() {
  startOOServer();
  }

  private void startOOServer() {
    if (applicationProperties != null) {
      if (applicationProperties.getStartOOServer()) {
        try {
          if (this.officeManager == null) {
            this.officeManager = new DefaultOfficeManagerConfiguration()
              .buildOfficeManager();
            this.officeManager.start();
            this.converterService = new ConverterService(this.officeManager);
          }
        } catch (Throwable e){
          logger.error(e);  
        }
      }
    }
  }

  public byte[] convert(byte[] inputData, String sourceExtension, String targetExtension) {
    byte[] result = null;

    startOOServer();
    ...
下面是ApplicationProperties的代码段

@Component
public class ApplicationProperties implements IApplicationProperties {

  /* Use the appProperties bean defined in WEB-INF/applicationContext.xml
   * which in turn uses resources/server.properties
   */
  @Resource(name="appProperties")
  private Properties appProperties;

  public Boolean getStartOOServer() {
    String val = appProperties.getProperty("startOOServer", "false");
    if( val == null ) return false;
    val = val.trim();
    return val.equalsIgnoreCase("true") || val.equalsIgnoreCase("on") || val.equalsIgnoreCase("yes");
  }
(来自Dunes comment的链接)在构建对象之后发生。因此,在构造函数完成之前不会设置它们


如果您需要运行一些初始化代码,您应该能够将构造函数中的代码拉入一个方法中,并使用注释对该方法进行注释。

要在构造时注入依赖项,您需要将构造函数标记为类似的
@Autowired
注释

@Autowired
public DocumentManager(IApplicationProperties applicationProperties) {
  this.applicationProperties = applicationProperties;
  startOOServer();
}

是的,两个答案都是正确的

老实说,这个问题实际上与post类似

错误的根本原因可以在Spring参考文档()中解释,如下所示:

自动连接字段

字段在构建bean之后,在任何 配置方法被调用

但是SpringDoc中这句话背后的真正原因是Spring中Bean的生命周期。这是Spring设计理念的一部分

这是: Bean需要先初始化,然后才能注入诸如field之类的属性。这就是bean的设计方式,所以这才是真正的原因


我希望这个答案对你有帮助

正如文档中所说的——感谢链接,为了便于查找,我将把它添加到答案中。谢谢,我还没有遇到关键的语句“字段在构建bean之后立即注入…”。我已经尝试过@PostConstruct注释,这正是我所需要的。如果能发布一个关于@PostConstruct@Tim的链接,我会很高兴的。谢谢!我将答案链接更新到了Spring3.2版本,并且还添加了Spring3.2版本的链接。实际上我认为这应该是首选答案。基于构造函数的依赖项注入方法非常适合强制组件。使用这种方法,spring框架还能够检测组件的循环依赖性(如A依赖于B,B依赖于C,C依赖于A)。使用setter或autowired字段的注入样式能够将未完全初始化的bean注入到您的字段中,从而使事情变得更加混乱。