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


89

下面显示的是我尝试引用我的ApplicationProperties bean的代码片段。当我从构造函数中引用它时,它为null,但是从另一个方法中引用时,它很好。到现在为止,我在其他类中使用此自动装配的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");
  }

Answers:


179

自动装配(沙丘评论的链接)发生在构造对象之后。因此,直到构造函数完成后才设置它们。

如果您需要运行一些初始化代码,则应该能够将构造函数中的代码放入方法中,并使用注释该方法@PostConstruct



感谢您的链接,我将其添加到答案中以便于查找。
nicholas.hauschild

2
谢谢,我还没有遇到关键的声明“在构造bean之后立即注入了字段...”。我尝试了@PostConstruct批注,而这正是我所需要的。
hairyone 2011年


@蒂姆,谢谢!我将答案链接更新为Spring 3.2版本,并且还添加了链接的Spring 3.2版本。
nicholas.hauschild 2013年

44

要在构造时注入依赖项,您需要@Autowired像这样用注释标记构造函数。

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

2
实际上,我认为这应该是首选的答案。基于构造函数的依赖注入方法非常适合于强制性组件。使用这种方法,spring框架也将能够检测对组件的周期性依赖关系(如A依赖于B,B依赖于C,C依赖于A)。使用setter或autowired字段的注入样式能够将未完全初始化的bean注入您的字段,从而使事情变得更加混乱。
Seakayone
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.