web-dev-qa-db-ja.com

@Autowired Beanは、別のBeanのコンストラクターで参照されるとnullです

以下に示すのは、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");
  }
84
hairyone

自動配線 (砂丘コメントからのリンク)は、オブジェクトの構築後に発生します。したがって、コンストラクターが完了するまで設定されません。

初期化コードを実行する必要がある場合は、コンストラクター内のコードをメソッドにプルし、そのメソッドに @PostConstruct

169

構築時に依存関係を注入するには、コンストラクターに@Autowired注釈を付ける必要があります。

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