Bug:引入Feign后触发了2次、4次ContextRefreshedEvent

Bug:引入Feign后发现监控onApplication中ContextRefreshedEvent事件触发了2次或者4次。

【原理】在Spring的文档注释中提示到: Event raised when an {@code ApplicationContext} gets initialized or refreshed.即当 ApplicationContext 进行初始化或者刷新时都会发送该事件。只有 finishRefresh() 方法里面会发送该事件,而该方法又只有 refresh() 方法调用,在 refresh() 方法中有这些注释: Load or refresh the persistent representation of the configuration, which ight be from Java-based configuration, an XML file, a properties file, a elational database schema, or some other format. As this is a startup method, it should destroy already created singletons if it fails, to avoid dangling resources. In other words, after invocation of this method, either all or no singletons at all should be instantiated.加载或者刷新配置文件,由于这是一个启动方法,如果失败,它应该销毁已经创建的单例,以避免悬空资源。换句话说,在调用这个方法前,要么全部实例化,要么根本不实例化。在初始化 openFeign 组件的最后,会调用 SubContext 的 refresh()操作,最终会触发 SubContext 发出ContextRefreshedEvent事件。

为啥出现多次触发ContextRefreshedEvent】监控类的每个ApplicationContext都会加载两次。在 Spring 框架中,事件(Event)是会沿着 Context 层次向上传播。简单来说子 Context 发出初始化完成事件,进而引发父 Context 也发出相同事件,而父 Context 此时并没有真正初始化完成。

  • AnnotationConfigApplicationContext~A
  • AnnotationConfigServletWebServerApplicationContext~B
  • AnnotationConfigApplicationContext~C

监控类#1 每个ApplicationContext触发4次ContextRefreshEvent,下为父子关系:

  • A:bootstrap:@21947
    • B:fkgss-serviceproxy-1:@17804
      • C:FeignContext-dc-inboundaa-rooladc:@17795,触发2次
    • B:fkgss-serviceproxy-1:@17804,触发2次

监控类#2 只触发2次ContextRefreshEvent。

  • A:bootstrap:@21932
    • B:fkgss-serviceproxy-1:@17807
      • C:FeignContext-dc-inboundaa-rooladc:@17799,触发1次
    • B:fkgss-serviceproxy-1:@17807,触发1次

【验证】新增一个Feign,会出现三次,验证是父子上下文导致。监控类#2问题解决。

  • 空白项目接入监控类#1模块,验证是否因为外部SDK原因导致:触发1次。
  • 父子项目接入监控类#1:触发1次。
  • 接入OpenFeign的同时接入监控类#1:触发1次。

=========>XX项目问题<=========

可能因为kgs中引入多个监控类#1:检索后没有发现。打印Thread.dumpStack()后:

  • 在第一个堆栈中,onApplicationEvent 方法位于 监控类#1类中,该方法是在 SimpleApplicationEventMulticaster 发布的事件中触发的。该事件通常在 finishRefresh 或 refresh 方法调用时触发,这些方法是在 Spring Boot 应用程序启动时执行的。
  • 在第二个堆栈中,onApplicationEvent 方法被通过 CGLIB 动态代理调用。CGLIB 代理的存在通常意味着 SeqNo 类被 Spring AOP 代理了,因此通过代理调用的 onApplicationEvent 可能触发了额外的逻辑,如切面增强、方法拦截等。

【触发条件】

  • Spring Event Multicasting:SimpleApplicationEventMulticaster 会为每个事件调用所有的事件监听器(如 SeqNo.onApplicationEvent)。因此,每当 ContextRefresh 事件发布时,监听器(如 SeqNo)会被触发一次。
  • CGLIB 代理的影响:由于 SeqNo 类可能是被 AOP 代理的,因此代理类的调用可能会导致同一方法被调用多次。具体来说,CGLIB 代理会生成一个新的类,并将对 SeqNo 方法的调用拦截和代理。这种代理逻辑可能导致事件监听方法被多次调用,导致 onApplicationEvent 被触发两次。

验证监控类#1是否是代理类

搜索日志发现:Bean '监控类#1' of type [******] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying);通常是由于 Spring 容器中的 Bean 在创建和初始化的过程中未能完全处理,导致该 Bean 无法被所有的 BeanPostProcessor 处理,尤其是无法进行自动代理。正是因为Feign提前触发ContextRefresh 。这也是为啥没办法通过BeanPostProcessor#postProcessAfterInitialization判断监控类#1是否被代理的原因。

【最后校验】

于是等【主上下文】加载完后,确定监控类#1被代理: 代理对象和原始 Bean 双重监听事件: 当事件发布时,Spring 容器会调用所有监听器的 onApplicationEvent 方法。由于 AOP 代理创建了一个新的 Bean 实例,该代理实例也会处理事件。因此,事件会被触发两次:

  • 一次是原始的 Bean 实例(即没有代理的实例)。
  • 另一次是代理实例。

事件监听机制: Spring 的事件监听机制是基于 Bean 的类型而不是 Bean 的实际实例。如果该 Bean 被 AOP 代理了,代理对象依然会注册为一个事件监听器,从而导致事件会被处理两次。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu20.04从零安装IsaacSim/IsaacLab

Ubuntu20.04从零安装IsaacSim/IsaacLab 电脑硬件配置&#xff1a;安装Isaac sim方案一&#xff1a;pip安装方案二&#xff1a;预构建二进制文件安装1、安装ominiverse2、在ominiverse中安装isaac sim&#xff0c;下载最新的4.2版本 安装Isaac Lab1、IsaacLab环境克隆2、创建con…

低速接口项目之串口Uart开发(二)——FIFO实现串口数据的收发回环测试

本节目录 一、设计思路 二、loop环回模块 三、仿真模块 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计思路 串口数据的收发回环测试&#xff0c;最简单的硬件测试是把Tx和Rx连接在一起&#xff0c;然后上位机进行发送和接收测试&#xff0c;但是需要考虑到串…

算法编程题-排序

算法编程题-排序 比较型排序算法冒泡排序选择排序插入排序希尔排序堆排序快速排序归并排序 非比较型排序算法计数排序基数排序 本文将对七中经典比较型排序算法进行介绍&#xff0c;并且给出golang语言的实现&#xff0c;还包括基数排序、计数排序等非比较型的算法的介绍和实现…

【软考】系统架构设计师-信息系统基础

#信息系统基础核心知识点 信息系统5个基本功能&#xff1a;输入、存储、处理、输出和控制 诺兰模型&#xff1a;信息系统计划的阶段模型&#xff0c;6阶段 初始阶段&#xff0c;传播阶段&#xff0c;控制阶段&#xff0c;集成阶段&#xff0c;数据管理阶段&#xff0c;成熟阶…

【架构】主流企业架构Zachman、ToGAF、FEA、DoDAF介绍

文章目录 前言一、Zachman架构二、ToGAF架构三、FEA架构四、DoDAF 前言 企业架构&#xff08;Enterprise Architecture&#xff0c;EA&#xff09;是指企业在信息技术和业务流程方面的整体设计和规划。 最近接触到“企业架构”这个概念&#xff0c;转念一想必定和我们软件架构…

使用低成本的蓝牙HID硬件模拟鼠标和键盘来实现自动化脚本

做过自动化脚本的都知道&#xff0c;现在很多传统的自动化脚本方案几乎都可以被检测&#xff0c;比如基于root&#xff0c;adb等方案。用外置的带有鼠标和键盘功能集的蓝牙HID硬件来直接点击和滑动是非常靠谱的方案&#xff0c;也是未来的趋势所在。 一、使用蓝牙HID硬件的优势…

数据结构-二叉树_堆

目录 1.二叉树的概念 ​编辑1.1树的概念与结构 1.2树的相关语 1.3 树的表示 2. ⼆叉树 2.1 概念与结构 2.2 特殊的⼆叉树 2.2.2 完全⼆叉树 2.3 ⼆叉树存储结构 2.3.1 顺序结构 2.3.2 链式结构 3. 实现顺序结构⼆叉树 3.2 堆的实现 3.2.2 向下调整算法 1.二叉树的概…

【FPGA开发】AXI-Full总线接口介绍、FPGA搭建仿真平台

文章目录 协议解读接口介绍AW—写地址通道W—写数据通道B—写响应通道AR—读地址通道R—读数据通道 FPGA搭建仿真平台 本文主要介绍AXI-FULL的相关基础内容&#xff0c;AXI-Lite请移步&#xff1a; 【FPGA开发】AXI-Lite总线协议解读、Verilog逻辑开发与仿真、Alex Forencich代…

【已解决】“EndNote could not connect to the online sync service”问题的解决

本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决&#xff1a; 这个方法虽然能解决&#xff0c;但工程量太大&#xff0c;每次做完得歇半天身体才能缓过来。 后来再遇到该问…

Python深度学习环境配置(Pytorch、CUDA、cuDNN),包括Anaconda搭配Pycharm的环境搭建以及基础使用教程(保姆级教程,适合小白、深度学习零基础入门)

全流程导览 一、前言二、基本介绍2.1全过程软件基本介绍2.1.1 Pytorch2.1.2 Anaconda2.1.3 Pycharm2.1.4 显卡GPU及其相关概念2.1.5 CUDA和cuDNN 2.2 各部分相互间的联系和安装逻辑关系 三、Anaconda安装3.1安装Anaconda3.2配置环境变量3.3检验是否安装成功 四、Pycharm安装五、…

Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片段

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

python成长技能之正则表达式

文章目录 一、认识正则表达式二、使用正则表达式匹配单一字符三、正则表达式之重复出现数量匹配四、使用正则表达式匹配字符集五、正则表达式之边界匹配六、正则表达式之组七、正则表达式之贪婪与非贪婪 一、认识正则表达式 什么是正则表达式 正则表达式&#xff08;英语&…

OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;分享&#xff5c;16个含源码和数据集的计算机视觉实战项目 本文将分享16个含源码和数据集的计算机视觉实战项目。具体包括&#xff1a; 1. 人…

Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

HarmonyOs鸿蒙开发实战(17)=>沉浸式效果第二种方案一组件安全区方案

1.沉浸式效果的目的 开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感&#xff0c;从而使用户获得最佳的UI体验。 2.组件安全区方案介绍 应用在默认情况下窗口背景绘制范围是全屏&#xff0c;但UI元素被限制在安全区内…

五天SpringCloud计划——DAY1之mybatis-plus的使用

一、引言 咱也不知道为啥SpringCloud课程会先教mybatis-plus的使用&#xff0c;但是教都教了&#xff0c;就学了吧&#xff0c;学完之后觉得mybatis-plus中的一些方法还是很好用了&#xff0c;本文作为我学习mybatis-plus的总结提升&#xff0c;希望大家看完之后也可以熟悉myba…

Matlab 答题卡方案

在现代教育事业的飞速发展中&#xff0c;考试已经成为现代教育事业中最公平的方式方法&#xff0c;而且也是衡量教与学的唯一方法。通过考试成绩的好与坏&#xff0c;老师和家长可以分析出学生掌握的知识多少和学习情况。从而老师可以了解到自己教学中的不足来改进教学的方式方…

丹摩|丹摩助力selenium实现大麦网抢票

丹摩&#xff5c;丹摩助力selenium实现大麦网抢票 声明&#xff1a;非广告&#xff0c;为用户体验 1.引言 在人工智能飞速发展的今天&#xff0c;丹摩智算平台&#xff08;DAMODEL&#xff09;以其卓越的AI算力服务脱颖而出&#xff0c;为开发者提供了一个简化AI开发流程的强…

【生成数据集EXCEL文件】使用生成对抗网络GAN生成数据集:输出生成数据集EXCEL

本文采用MATLAB编程&#xff0c;使用生成对抗网络GAN生成数据集&#xff1a;输出生成数据集EXCEL格式文件&#xff0c;方便大家使用。 实际工程应用中&#xff0c;由于经济成本和人力成本的限制&#xff0c;获取大量典型的有标签的数据变得极具挑战&#xff0c;造成了训练样本…

cocos creator 3.8 一些简单的操作技巧,材质的创建 1

这是一个飞机的3D模型与贴图 导入到cocos中&#xff0c;法线模型文件中已经包含了mesh、material、prefab&#xff0c;也就是模型、材质与预制。界面上创建一个空节点Plane&#xff0c;将模型直接拖入到Plane下。新建材质如图下 Effect属性选择builtin-unlit&#xff0c;不需…