Hello World

Spring 中初始化一个Bean对象时依赖其他Bean对象空指针异常

1. Bean依赖关系

  一个配置类的Bean,一个实例Bean;

  实例Bean初始化时需要依赖配置类的Bean;

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空指针异常;

  

3. 原因分析

  spring在实例化Bean时,先通过反射调用构造方法生成一个基本对象,然后再填充属性(参考:spring bean 的生命周期);

  填充属性之前属性值都为默认值,引用类为null,构造方法中使用属性对象时属性对象还未被设置,所以为null;

4. 解决方案

4.1 方案一

  构造器中将Bean作为参数显式的传入;

@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);
        }
    }
}

 

 

  

posted @ 2019-01-11 20:10  小小忧愁米粒大  阅读(6753)  评论(0编辑  收藏  举报
瞅啥瞅,好好看书