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); } } }
如果文章对您有所帮助,可以点一下推荐