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

hai*_*one 86 java spring autowired

下面显示的是一段代码,我尝试引用我的ApplicationProperties bean.当我从构造函数引用它时它是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();
    ...
Run Code Online (Sandbox Code Playgroud)

以下是ApplicationProperties的s片段...

@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");
  }
Run Code Online (Sandbox Code Playgroud)

nic*_*ild 172

自动装配(来自Dunes评论的链接)在构造对象之后发生.因此,在构造函数完成之后才会设置它们.

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

  • 正如文档中所述 - http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/Autowired.html (3认同)
  • 谢谢,我还没有看到关键的声明"在构建一个bean之后就注入了字段......".我已经尝试过@PostConstruct注释,这正是我需要的. (2认同)

mR_*_*r0g 44

要在构造时注入依赖项,您需要将构造函数标记为@Autowiredannoation.

@Autowired
public DocumentManager(IApplicationProperties applicationProperties) {
  this.applicationProperties = applicationProperties;
  startOOServer();
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上我认为这应该是首选答案.基于构造函数的依赖注入方法非常适合于强制组件.使用这种方法,spring框架也能够检测组件的循环依赖性(如A中的B取决于B,B取决于C,C取决于A).使用setter或autowired字段的注入样式能够将未完全初始化的bean注入到字段中,使事情变得更加混乱. (2认同)