Bean-компонент @Autowired имеет нулевое значение при ссылке в конструкторе другого компонента - PullRequest
81 голосов
/ 14 июня 2011

Ниже показан фрагмент кода, в котором я пытаюсь сослаться на мой компонент ApplicationProperties. Когда я ссылаюсь на него из конструктора, он имеет значение null, но при ссылке на него из другого метода это нормально. До сих пор у меня не было проблем с использованием этого bean-компонента в других классах. Но я впервые пытался использовать его в конструкторе другого класса.

В приведенном ниже фрагменте кода 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");
  }

Ответы [ 2 ]

165 голосов
/ 14 июня 2011

Автопроводка (ссылка из комментария Дюны) происходит после постройки объекта. Поэтому они не будут установлены до завершения конструктора.

Если вам нужно запустить некоторый код инициализации, вы должны иметь возможность вытянуть код в конструкторе в метод и аннотировать этот метод с помощью @PostConstruct.

43 голосов
/ 14 июня 2011

Чтобы вводить зависимости во время построения, вам нужно пометить конструктор с пометкой @Autowired, например, так.

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