Spring Environment 注入引起NPE问题排查

文章目录

        • 背景
        • 原因分析
          • 1)Spring Aware Bean 是什么?
          • 2)从 Spring Bean 的生命周期入手
        • 解决方案

背景

写业务代码遇到使用 Spring Environment 注入为 null 的情况,示例代码有以下两种写法,Environment 实例都无法注入成功,均为 null。

  • 写法一:直接在业务 Bean 中注入 Environment 类
public class IPayInstitutionManager {
  
  @Autowire
  private Environment environment;
  
  public IPayInstitutionManager() {
    log.info("IPayInstitutionManager start to init...");
    log.info("IPayInstitutionManager environment:{}", environment);
    log.info("testPrivate:{}", environment.getProperty("test.key"));
    init();
  }
}
  • 写法二:使用 EnvironmentAware
public class IPayInstitutionManager implements EnvironmentAware {
  
  private Environment environment;
  
  @Override
  public void setEnvironment(Environment environment) {
    this.environment = environment;
    log.info("IPayInstitutionManager#setEnvironment environment:{}", environment);
    log.info("IPayInstitutionManager#setEnvironment value:{}", environment.getProperty("test.key"));
  }
  
  public IPayInstitutionManager() {
    log.info("IPayInstitutionManager start to init...");
    log.info("IPayInstitutionManager environment:{}", environment);
    log.info("testPrivate:{}", environment.getProperty("test.key"));
    init();
  }
}
原因分析
1)Spring Aware Bean 是什么?

Aware 即”察觉的,注意到的,感知的”,xxxAware 也就是对xxx感知的。Spring 的依赖注入使业务 Bean 对 Spring 容器的存在是没有意识的,但有时候业务 Bean 需要对 Spring 容器有感知,能使用 Spring 容器内置的组件(如 ApplicationContext、BeanFactory 等)。就出现了以下 Aware Bean(具体使用方法不再简介):

  • ApplicationContextAware:获得当前应用上下文
  • EnviromentAware:获得环境变量
  • BeanNameAware:获取容器中bean名称
  • BeanFactoryAware:获得bean工厂
2)从 Spring Bean 的生命周期入手

上面两个例子很容易猜想到 IPayInstitutionManager 进行实例化调用其构造方法过程中,environment 并未执行初始化,以写法二从启动日志中可验证:IPayInstitutionManager 构造函数先于 environment 实例化

在这里插入图片描述

回到 Bean 的生命周期,如下图所示:

在这里插入图片描述

很明显,IPayInstitutionManager 调用构造方法实例化时,Environment 并未完成初始化(图中 EnvironmentAware.setEnvironment 结点)。即若 Spring 未进行 EnvironmentAware.setEnvironment 回调前,Environment 并不能使用,这也是为什么像 Environment、ApplicationContext 等 Spring 内部组件不能直接 @Autowire 注入的原因,必须要实现 Aware Bean

解决方案

结合 Bean 生命周期图,如果要在代码中使用 Environment 等 Spring 组件时,时机要晚于图中 BeanPostProcessor.postProcessBeforeInitialization 方法执行时机即可,比如使用 @PostConstruct 注解,实现 InitializingBean 接口等。这里给出一个示例:

public class IPayInstitutionManager implements EnvironmentAware, InitializingBean {
  
  private Environment environment;
  
  @Override
  public void setEnvironment(Environment environment) {
    this.environment = environment;
  }
  
  @Override
  public void afterPropertiesSet() {
    log.info("testPrivate:{}", environment.getProperty("test.key")); // 正常输出
    init();
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/263229.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为OD机试 - 多段线数据压缩(Java JS Python C)

题目描述 下图中,每个方块代表一个像素,每个像素用其行号和列号表示。 为简化处理,多线段的走向只能是水平、竖直、斜向45度。 上图中的多线段可以用下面的坐标串表示:(2,8),(3,7),(3,6),(3,5),(4,4),(5,3),(6,2),(7,3),(8,4),(7,5)。 但可以发现,这种表示不是最简的,…

RK3568驱动指南|第八篇 设备树插件-第80章 注册attribute实验

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…

【C++入门到精通】互斥锁 (Mutex) C++11 [ C++入门 ]

阅读导航 引言一、Mutex的简介二、Mutex的种类1. std::mutex (基本互斥锁)2. std::recursive_mutex (递归互斥锁)3. std::timed_mutex (限时等待互斥锁)4. std::recursive_timed_mutex (限时等待…

【数字图像处理】实验二 图像变换

图像变换 一、实验内容: 1. 熟悉和掌握利用Matlab工具进行数字图像的读、写、显示等数字图像处理基本步骤。 2. 熟练掌握各种图像变换的基本原理及方法。 3. 能够从深刻理解图像变换,并能够思考拓展到一定的应用领域。…

多层负载均衡实现

1、单节点负载均衡 1)站点层与浏览器层之间加入了一个反向代理层,利用高性能的nginx来做反向代理 2)nginx将http请求分发给后端多个web-server 优点: 1)DNS-server不需要动 2)负载均衡:通过ngi…

OGG同步异构数据库-表字段变更重新读取异构文件测试验证

OGG同步异构数据库-表字段变更重新读取异构文件测试验证 删除前源和目标端的同步情况: 配置文件信息: 源端: GGSCI (ITSMdoc-236-63) 4> view param etest extract etest setenv (MYSQL_HOME“/data/mysql-5.7.26”) tranlogoptions al…

研究生课程 |《矩阵论》复习

文章目录 【一(18)】填空题【二(10)】范数证明【三(15)】矩阵函数1 计算 e A t e^{At} eAt2 求微分方程的解 【四(10)】QR分解【五(10)】Gerschgorim隔离特征值【六(15)】 A A^ A计算及求解线性方程组1 计算满秩分解2 计算 A A^ A3 判断线性方程组解是否存在 【七(15)】线性…

快速开发教务管理应用,课程表微信小程序源码

介绍 课程表微信小程序源码 快速开发教务管理应用 对接微信公众号每日课表推送 三种导入课表方式可供选择 班级课表导入 爬虫导入课表 学号导入课表

with torch.no_grad()在Pytorch中的应用

with torch.no_grad()在Pytorch中的应用 参考: https://blog.csdn.net/qq_24761287/article/details/129773333 https://blog.csdn.net/sazass/article/details/116668755 在学习Pytorch时,老遇到 with torch.no_grad(),搞不清其作用&#…

P2 H264码流结构分析——Annexb与MP4格式的区别 (中)

前言 从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ 🔥 推荐专栏2: 《Linux C应用编程(概念类)_Ch…

如何使用Java的GeoTools地理库计算WGS84坐标下的两个经纬度之间得距离

介绍 本章讲解如何使用Java的GeoTools地理库计算基于WGS84坐标的两点之间的距离。适用于后台服务的距离计算。 GeoTools介绍 GeoTools是开源的Java地理信息计算库。GeoServer地图引擎就是基于GeoTools库构建得地图服务,可以说非常强大。 官网地址:https://docs.geotools.o…

python/C 生成beta分布的随机数

python/C 生成beta分布的随机数 文章目录 python/C 生成beta分布的随机数前言一、beta分布理论知识二、python 生成服从beta分布的随机数三、C语言生成服从beta分布的随机数 前言 想把一个算法用C语言实现,其中涉及到了beta分布取随机数,记录一下结果 一…

【Java】网络编程-TCP回显服务器代码编写

前面我们讲了基于UDP的网络编程 UDP回显服务器 UDP字典服务器 下面我们来讲基于TCP的回显服务编写 1、服务器 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; impo…

25、新加坡南洋理工、新加坡国立大学提出FBCNet:完美融合FBCSP的CNN,EEG解码SOTA水准![抱歉老师,我太想进步了!]

前言: 阴阳差错,因工作需要,需要查阅有关如何将FBCSP融入CNN中的文献,查阅全网,发现只此一篇文章,心中大喜,心想作者哪家单位,读之,原来是自己大导(新加坡工…

冬天天冷早安问候语关心话,愿我的每句话都能带给你温馨

1、送你一声问候,为你驱走冬日严寒,送你一份关怀,为你增添丝丝温暖,送你一句祝福,为你驱走所有不快,送你一份关爱,为你增添幸福无限,天虽寒了,我的关心犹在,愿…

Centos安装Docker及使用

文章目录 配置要求Centos安装Docker卸载docker(可选)安装docker首先需要大家虚拟机联网,安装yum工具然后更新本地镜像源:然后输入安装docker命令:查看docker的版本 启动docker关闭防火墙接着通过命令启动docker 配置镜…

vscode debug c++代码

需要提前写好CMakeLists.txt 在tasks.json中写好编译的步骤,即tasks,如cmake … 和make -j 在lauch.json中配置可执行文件的路径和需要执行tasks中的哪一个任务 具体步骤: 1.写好c代码和CMakeLists.txt 2.配置tasks.json 终端–>配置任务…

竞赛保研 基于CNN实现谣言检测 - python 深度学习 机器学习

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于CNN实现谣言检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐&am…

Jmeter测试时遇到的各种乱码问题及解决

在Jmeter中显示乱码 遇到的问题:csv文件中有的用户名是中文的,接口使用该用户名入参时,查看结果树中看到,中文名显示为一堆乱码。 解决的方法: 应该是文件编码与jmeter编码不一致导致的。 1)新建一个tx…

使用Python从图像中提取表格

有什么作用? 与深度学习解决方案相比,这个轻量级的包不需要训练和最小化参数化。它提供了以下功能: 识别图像和PDF文件中的表格,包括在表格单元级别的边界框。 通过支持OCR服务/工具(Tesseract、PaddleOCR、AWS Textract、Google Vision和Azure OCR目前支持)来提取表格内…