线上出 BUG 原因竟是 Spring 父子容器,反手我就去扒了它的底裤
- J3
- Spring(父子容器 # BUG)
1、事情的缘由
一天,J3接到个小需求,对进入数据库的数据线索做拦截处理。进入数据库的数据具体要做三个渠道校验A、B、C而这三个渠道的校验规则都各不相同,只要这其中一个渠道不满足那就不符合入库要求,则不可入库。
看到这个,J3内心是无比的窃喜,因为太简单了。说着J3就对着需求写出了下面的代码:
@RestController
@RequestMapping("/insert")
public class InsertController {@Autowiredprivate ApplicationContext applicationContext;@PostMapping("/")public void doInsert(@RequestBody Entity entity){// 校验,核心逻辑Map<String, CheckChain> beansOfType = applicationContext.getBeansOfType(CheckChain.class);beansOfType.entrySet().forEach(entry -> {if (!entry.getValue().check(entity)){return;}});// 往下调用业务类执行插入// ...}
}
// 校验接口
public interface CheckChain {Boolean check(Entity e1);
}
// A渠道校验逻辑
@Component
public class ACheckChain implements CheckChain{@Overridepublic Boolean check(Entity e1) {// 校验逻辑return Boolean.TRUE;}
}
// B渠道校验逻辑
@Component
public class BCheckChain implements CheckChain{@Overridepublic Boolean check(Entity e1) {// 校验逻辑return Boolean.TRUE;}
}
// C渠道校验逻辑
@Component
public class CCheckChain implements CheckChain{@Overridepublic Boolean check(Entity e1) {// 校验逻辑return Boolean.TRUE;}
}
以上代码,是在 Spring 环境下运行的,我是通过对每个校验规则单独进行的测试,所有规则都测试完毕后就直接上线使用了。
而隐患就来了,那就是只单独测试了每个校验规则,没有整个逻辑走一遍,从 Controller 出发到最终的数据落库这整个流程。此时J3还不知道,他这菜逼写了个大 Bug,而且还是四个月之后才被人发现的。
就在前几天公司运营那边反馈数据拦截有问题,该拦的没拦住,这时我才注意到这个问题,立马去排查相关实现代码,经过了一系列的排查最终发现了端倪,看下面代码:
Controller 中能通过 ApplicationContext 拿到 @Component 扫描的 bean 吗?在 Spring 中,答案是不能的。
所以,这是那个二比写的代码,我立马看代码提交记录,原地楞了几秒,居然是我写的代码,还是四个月前。
定位出问题后,我也大致清楚问题的根本原因了,就先将线上问题修复(怕耽误老板赚),之后我再来好好扒一扒这个问题的细节。
2、Spring 父子容器
通过上面的事情描述,相信很多人都已经猜到问题出在什么关键点上了:Spring 父子容器
。
那既然这,咱们就来扒一扒它的底(原理)吧!
分析原理前,我先说明一下接下来我们是要干嘛。
- 分析父容器启动流程;
- 父容器中存放那些 Bean;
- 分析子容器启动流程;
- 子容器中存放那些 Bean;
- Controller 中注入的 IOC 容器是子容器还是父容器;
- Service 中注入的 IOC 容器是子容器还是父容器;
- 通过 IOC 容器如何获取 Bean;
2.1、环境搭建
父子容器问题,我觉得最好是自己搭建一个 Spring 和 Spring MVC 整合的架子出来,这样好定位分析其中的原理。
这是本人搭建好的环境(JDK11),大家不想自己搭建的可以直接 clone 一份
线上出 BUG 原因竟是 Spring 父子容器,反手我就去扒了它的底裤相关推荐
- 线上出bug了?别怕,这么定位!
小编推荐: Fundebug提供JS.微信小程序.微信小游戏,Node.js和Java错误监控.真的是一个很好用的错误监控服务,众多大佬公司都在使用. 摘要: Source Map还是很神奇的. 原文 ...
- 服务器芯片缺货吗,华为线上缺货的原因找到了!芯片只是其一!线下销售员说出实话!...
原标题:华为线上缺货的原因找到了!芯片只是其一!线下销售员说出实话! 大家都知道,华为如今不少的机型都很缺货.而究其根本的原因还是因为芯片供应上出现了问题.如果说没有芯片上的限制,或许华为不会面临当下 ...
- Spring父子容器
目录 什么是父子容器 什么是容器 如何形成父子关系 父子容器的特点 父子容器的作用 引用 什么是父子容器 什么是容器 当我们使用spring的时候,我们经常会提到一个概念,IOC容器,IOC容器就是具 ...
- spring注解开发配置spring父子容器
spring注解开发配置spring父子容器 官网 https://docs.spring.io/spring-framework/docs/current/spring-framework-refe ...
- 赶紧的,用户已经打电话来投诉线上出问题了
出bug了 如标题所示,用户资金获取失败,线上某个服务通过dubbo调用接口都返回异常. 赶紧连上服务器看日志,进去一看吓到了. Cause: java.sql.SQLException: conne ...
- python close_wait_线上大量CLOSE_WAIT原因深入分析
这一次重启真的无法解决问题了:一次 MySQL 主动关闭,导致服务出现大量 CLOSE_WAIT 的全流程排查过程. 近日遇到一个线上服务 socket 资源被不断打满的情况.通过各种工具分析线上问题 ...
- mysql 大量close wait_线上大量CLOSE_WAIT原因排查
近日遇到一个线上服务 socket 资源被不断打满的情况.通过各种工具分析线上问题,定位到问题代码.这里对该问题发现.修复过程进行一下复盘总结. 先看两张图.一张图是服务正常时监控到的 socket ...
- 线上内存溢出原因排除
[分析] 如果机器比较紧缺,第一时间要恢复应用,可以直接先将该节点下线,保存线程栈快照,和堆内存快照.然后进行重启. 生产机器一般都是集群部署,如果只是某一台出现这种情况,可以不着急立即重启,保存现场 ...
- 软件测试面试中关于线上bug,线上出现bug测试人员怎么办
常在河边走,哪能不湿鞋,即使测试在工作中已经小心再小心了,但有时还是可能会出现线上问题,真是个悲伤的故事,然而纵然悲伤也需要有个结局,那么项目上线出现bug,测试人员该肿么办呢? 首先要做的是重现这个 ...
最新文章
- WEP自动破解工具wesside-ng
- MaterialEditText 控件学习
- 当我们在聊 Serverless 时你应该知道这些
- CocoaPods 的使用与一些异常情况的处理
- Android studio java文件显示变为红色J
- QT的QQmlApplicationEngine类的使用
- jrockit_JRockit JRCMD教程
- MockWebServer[45678] connection from null failed: java.net.SocketException
- intellij idea中解决java.lang.VerifyError: Expecting a stackmap frame at branch target的方法
- java类型之间的转换_JAVA基本数据类型及之间的转换
- ubuntu 16.04 python3.4 升级为 python3.6
- 一个android应用开发的感悟
- Keil代码自动对齐 VS对齐功能
- c语言中文件的存储,急求如何将下列C语言程序数据存储到文件中?
- gis如何加入emf图片_ArcGIS教程:地图导出格式,教你如何选择
- 视频教程-excel提高效率的实用技巧-Office/WPS
- spring boot oauth2 facebook
- 修改导航栏的背景色和字体颜色
- Uniapp云开发(Uniapp入门)
- 周志华机器学习--线性模型