Spring 中初始化一個Bean對象時依賴其餘Bean對象空指針異常

1. Bean依賴關係

  一個配置類的Bean,一個實例Bean;html

  實例Bean初始化時須要依賴配置類的Bean;spring

1.1 配置類Bean

@ConfigurationProperties(prefix = "system")
public class SystemConfig {

    private Integer type;

    private String rootPath;
}

1.2 實例Bean

@Component
public class HDFSFileHandler implements FileHandler {

    @Autowired
    private SystemConfig config;

    private FileSystem fileSystem;

    public HDFSFileHandler(){
        start();
    }

    /**
     * 初始化 fileSystem
     */
    private void start()  {
        try {
            // 此處 config 空指針異常
            if (SystemConstant.FILE_SYSTEM_HDFS.equals(config.getType())){
                String uri = "hdfs://" + config.getHdfsIp() + ":" + config.getHdfsPort();
                fileSystem = FileSystem.get(new URI(uri), new Configuration(), "hadoop");
                log.debug("uri:" + uri);
                log.debug("fileSystem:" + fileSystem);
            }
        } catch (Exception e) {
            log.error("init fileSystem occur a exception",e);
        }
    }
}

 

2. 問題現象

  實例Bean初始化時配置類Bean空指針異常;oop

  

3. 緣由分析

  spring在實例化Bean時,先經過反射調用構造方法生成一個基本對象,而後再填充屬性(參考:spring bean 的生命週期);this

  填充屬性以前屬性值都爲默認值,引用類爲null,構造方法中使用屬性對象時屬性對象還未被設置,因此爲null;spa

4. 解決方案

4.1 方案一

  構造器中將Bean做爲參數顯式的傳入;debug

@Component
public class HDFSFileHandler implements FileHandler {

    private SystemConfig config;

    private FileSystem fileSystem;
  // 構造器顯式傳入參數 public HDFSFileHandler(SystemConfig config) {
        this.config = config;
        start();
    }

    /**
     * 初始化 fileSystem
     */
    private void start()  {
        try {
            
            if (SystemConstant.FILE_SYSTEM_HDFS.equals(config.getType())){
                String uri = "hdfs://" + config.getHdfsIp() + ":" + config.getHdfsPort();
                fileSystem = FileSystem.get(new URI(uri), new Configuration(), "hadoop");
                log.debug("uri:" + uri);
                log.debug("fileSystem:" + fileSystem);
            }
        } catch (Exception e) {
            log.error("init fileSystem occur a exception",e);
        }
    }
}

4.2  @Autowired + @PostConstruct

@Component
public class HDFSFileHandler implements FileHandler {

    @Autowired private SystemConfig config;

    private FileSystem fileSystem;

    public HDFSFileHandler() {
        start();
    }

    /**
     * 初始化 fileSystem
     */
    @PostConstruct
    private void start()  {
        try {
            if (SystemConstant.FILE_SYSTEM_HDFS.equals(config.getType())){
                String uri = "hdfs://" + config.getHdfsIp() + ":" + config.getHdfsPort();
                fileSystem = FileSystem.get(new URI(uri), new Configuration(), "hadoop");
                log.debug("uri:" + uri);
                log.debug("fileSystem:" + fileSystem);
            }
        } catch (Exception e) {
            log.error("init fileSystem occur a exception",e);
        }
    }
}
相關文章
相關標籤/搜索