簡體   English   中英

@Autowired bean 在另一個 bean 的構造函數中引用時為 null

[英]@Autowired bean is null when referenced in the constructor of another bean

下面顯示的是我嘗試引用我的 ApplicationProperties bean 的代碼片段。 當我從構造函數中引用它時,它是 null,但是當從另一種方法引用時它很好。 到目前為止,我在其他類中使用這個自動裝配的 bean 沒有問題。 但這是我第一次嘗試在另一個 class 的構造函數中使用它。

在 applicationProperties 下面的代碼片段中,當從構造函數調用時為 null,但在 convert 方法中引用時則不是。 我錯過了什么

@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 評論的鏈接)在 object 構建之后發生。 因此,在構造函數完成之前不會設置它們。

如果您需要運行一些初始化代碼,您應該能夠將構造函數中的代碼拉入一個方法中,並使用@PostConstruct注釋該方法。

要在構建時注入依賴項,您需要像這樣使用@Autowired注釋標記您的構造函數。

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

是的,兩個答案都是正確的。

說實話,這個問題其實和帖子Why is my Spring @Autowired field null類似? .

錯誤的根本原因可以在 Spring 參考文檔( Autowired )中解釋,如下:

自動連線字段

在構造 bean 之后,在調用任何配置方法之前,立即注入字段。

但 Spring 文檔中此語句背后的真正原因是 Spring中 Bean的生命周期。 這是 Spring 設計理念的一部分。

這是Spring Bean 生命周期概述 在此處輸入圖像描述 Bean需要先初始化,才能注入field等屬性。 這就是 bean 的設計方式,所以這才是真正的原因。

我希望這個答案對你有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM