当前位置: 首页 > news >正文

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 代理了,代理对象依然会注册为一个事件监听器,从而导致事件会被处理两次。

相关文章:

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

Bug&#xff1a;引入Feign后发现监控onApplication中ContextRefreshedEvent事件触发了2次或者4次。 【原理】在Spring的文档注释中提示到&#xff1a; Event raised when an {code ApplicationContext} gets initialized or refreshed.即当 ApplicationContext 进行初始化或者刷…...

最新‌VSCode保姆级安装教程(附安装包)

文章目录 一、VSCode介绍 二、VSCode下载 下载链接&#xff1a;https://pan.quark.cn/s/19a303ff81fc 三、VSCode安装 1.解压安装文件&#xff1a;双击打开并安装VSCode 2.勾选我同意协议&#xff1a;然后点击下一步 3.选择目标位置&#xff1a;点击浏览 4.选择D盘安装&…...

layui 表格点击编辑感觉很好用,实现方法如下

1. 在 HTML 页面中引入 layui 的相关资源文件&#xff1a;html <link rel"stylesheet" href"https://cdn.staticfile.org/layui/2.5.6/css/layui.css"> <script src"https://cdn.staticfile.org/layui/2.5.6/layui.js"></script&…...

三十一、构建完善微服务——API 网关

一、API 网关基础 系统拆分为微服务后&#xff0c;内部的微服务之间是互联互通的&#xff0c;相互之间的访问都是点对点的。如果外部系统想调用系统的某个功能&#xff0c;也采取点对点的方式&#xff0c;则外部系统会非常“头大”。因为在外部系统看来&#xff0c;它不需要也没…...

非对称之美(贪心)

非对称之美(贪心) import java.util.*; public class Main{public static void main(String[] arg) {Scanner in new Scanner(System.in);char[] ch in.next().toCharArray(); int n ch.length; int flag 1;for(int i 1; i < n; i) {if(ch[i] ! ch[0]) {flag …...

详细教程-Linux上安装单机版的Hadoop

1、上传Hadoop安装包至linux并解压 tar -zxvf hadoop-2.6.0-cdh5.15.2.tar.gz 安装包&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1u59OLTJctKmm9YVWr_F-Cg 提取码&#xff1a;0pfj 2、配置免密码登录 生成秘钥&#xff1a; ssh-keygen -t rsa -P 将秘钥写入认…...

C#桌面应用制作计算器进阶版01

基于C#桌面应用制作计算器做出了少量改动&#xff0c;其主要改动为新增加了一个label控件&#xff0c;使其每一步运算结果由label2展示出来&#xff0c;而当点击“”时&#xff0c;最终运算结果将由label1展示出来&#xff0c;此时label清空。 修改后运行效果 修改后全篇代码 …...

[开源] 告别黑苹果!用docker安装MacOS体验苹果系统

没用过苹果电脑的朋友可能会对苹果系统好奇&#xff0c;有人甚至会为了尝鲜MacOS去折腾黑苹果。如果你只是想体验一下MacOS&#xff0c;这里有个更简单更优雅的解决方案&#xff0c;用docker安装MacOS来体验苹果系统。 一、项目简介 项目描述 Docker 容器内的 OSX&#xff08…...

多模态大模型(4)--InstructBLIP

BLIP-2通过冻结的指令调优LLM以理解视觉输入&#xff0c;展示了在图像到文本生成中遵循指令的初步能力。然而&#xff0c;由于额外的视觉输入由于输入分布和任务多样性&#xff0c;构建通用视觉语言模型面临很大的挑战。因而&#xff0c;在视觉领域&#xff0c;指令调优技术仍未…...

【Linux】基于 Busybox 构建嵌入式 Linux(未完成)

嵌入式 Linux 1.需要 Toolchain 2.需要 Bootloader 3.需要嵌入式 Linux 基本组件&#xff1a; Linux kernelDTBRoot filesystem InitShellDaemonShared librariesConfiguration fileDevice nodeproc and sysKernel Module 基于 Busybox 构建 1.编译 Linux kernel 2.编译 …...

Unet++改进38:添加GLSA(2024最新改进方法)具有聚合和表示全局和局部空间特征的能力,这有利于分别定位大目标和小目标

本文内容:添加GLSA注意力机制 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 基于变压器的模型已经被广泛证明是成功的计算机视觉任务,通过建模远程依赖关系和捕获全局表示。然而,它们往往被大模式的特征所主导,导致局部细节(例如边界和小物体)的丢失…...

c++中mystring运算符重载

#include <iostream> #include <cstring>using namespace std;class mystring {char* buf; public:mystring(); //构造函数mystring(const char * str); //构造函数mystring(const mystring& str); //深拷贝函数void show(); //输出函数void setmystr(const my…...

图像处理 - 色彩空间转换

色彩空间转换的含义与原理 色彩空间转换是指将一种颜色模型或表示方式中的颜色数据映射到另一种颜色模型中的过程。色彩空间&#xff08;Color Space&#xff09;本质上是一个三维坐标系统&#xff0c;每个点都表示图像中的某种颜色。在实际应用中&#xff0c;由于不同的色彩空…...

MariaDB面试题及参考答案

什么是 MariaDB&#xff1f; MariaDB 是一个开源的关系型数据库管理系统&#xff0c;它是 MySQL 数据库的一个分支。它的主要目的是存储和管理数据&#xff0c;采用了关系模型&#xff0c;数据存储在表中&#xff0c;表之间可以通过关联建立关系。 从起源来讲&#xff0c;Maria…...

PostgreSQL常用字符串函数与示例说明

文章目录 coalesce字符串位置(position strpos)字符串长度与大小写转换去掉空格(trim ltrim rtrim)字符串连接(concat)字符串替换简单替换(replace)替换指定位置长度(overlay)正则替换(regexp_replace) 字符串匹配字符串拆分split_part(拆分数组取指定位置的值)string_to_array…...

力扣第58题:最后一个单词的长度

力扣第58题是 最后一个单词的长度&#xff0c;具体要求是给定一个字符串&#xff0c;找到其最后一个单词的长度。 题目描述 输入&#xff1a;一个由字母和空格组成的字符串 s&#xff0c;可以包含大小写字母和若干空格。 输出&#xff1a;最后一个单词的长度。 注意&#xf…...

【Maven】Nexus几个仓库的介绍

在 Nexus 仓库管理器中&#xff0c;maven-central、maven-public、maven-releases 和 maven-snapshots 是常用的 Maven 仓库类型。每个仓库都有其特定的用途和功能。以下是对这些仓库的详细介绍&#xff1a; 1. maven-central 类型&#xff1a;代理仓库&#xff08;Proxy Rep…...

SSH免密登陆

一、生成SSH密钥对 在客户端主机 ClientHost上&#xff0c;以 root用户身份生成SSH密钥对&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" # -t rsa&#xff1a;指定使用RSA算法 # -b 4096&#xff1a;指定密钥长度为4096位 # -C ""…...

【Linux】Namespace

一、概念 Linux Namespace 是 Linux 内核提供的一种特性&#xff0c;用于对系统资源进行隔离。通过 Namespace&#xff0c;不同的进程组可以拥有独立的系统资源视图&#xff0c;即使它们在同一台物理机器上运行。这种隔离机制使得容器技术成为可能&#xff0c;因为它允许在单个…...

SQLite 和 MySQL语法区别

SQLite 和 MySQL 在 SQL 语法上有一些差异&#xff0c;这些差异主要体现在数据类型、函数、表和索引的管理等方面。以下是一些主要的不同之处&#xff1a; 1. 数据类型 SQLite 支持的数据类型包括&#xff1a;TEXT, INTEGER, REAL, BLOB。动态类型系统&#xff0c;允许在插入…...

基于BERT的命名体识别(NER)

基于BERT的命名实体识别&#xff08;NER&#xff09; 目录 项目背景项目结构环境准备数据准备代码实现 5.1 数据预处理 (src/preprocess.py)5.2 模型训练 (src/train.py)5.3 模型评估 (src/evaluate.py)5.4 模型推理 (src/inference.py) 项目运行 6.1 一键运行脚本 (run.sh)6…...

华为云鸿蒙应用入门级开发者认证考试题库(理论题和实验题)

注意&#xff1a;考试链接地址&#xff1a;华为云鸿蒙应用入门级学习认证_华为云鸿蒙应用入门级开发者认证_华为云开发者学堂-华为云 当前认证打折之后是1元&#xff0c;之后原价700元&#xff0c;大家尽快考试&#xff01;考试题库里面答案不一定全对&#xff0c;但是可以保证…...

SpringBoot+React养老院管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1.入住合同文件上传2.添加和修改套餐的代码3.查看入住记录代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootReact框架开发的养老院管理系统。首先…...

使用element-plus el-table中使用el-image层级冲突table表格会覆盖预览的图片等问题

在日常开发项目中 使用element-plus 中表格中使用 el-image的点击图片出现图片预览 会出现以下问题 表格一行会覆盖预览的图片 鼠标滑过也会显示表格 el-image 的预览层级和表格的层级冲突导致的。 解决方法&#xff1a;有两种一种是直接使用样式穿透 第二种推荐方法 使用官网推…...

python读取Oracle库并生成API返回Json格式

一、安装必要的库 首先&#xff0c;确保已经安装了以下库&#xff1a; 有网模式 pip install flask pip install gevent pi install cx_Oracle离线模式&#xff1a; 下载地址&#xff1a;https://pypi.org/simple/flask/ # a. Flask Werkzeug-1.0.1-py2.py3-none-any.whl J…...

音视频入门基础:MPEG2-TS专题(5)——FFmpeg源码中,判断某文件是否为TS文件的实现

一、引言 通过FFmpeg命令&#xff1a; ./ffmpeg -i XXX.ts 可以判断出某个文件是否为TS文件&#xff1a; 所以FFmpeg是怎样判断出某个文件是否为TS文件呢&#xff1f;它内部其实是通过mpegts_probe函数来判断的。从《FFmpeg源码&#xff1a;av_probe_input_format3函数和AVI…...

每天10个vue面试题(九)

1、如何在组件中批量使用Vuex的getter属性&#xff1f; 使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中computed:{ ...mapGetters([total,discountTotal]) } 2、vue2和vue3的区别&#xff1f; 双向数据绑定不同&#xff1a;vue2 的双向数据绑定…...

Jenkins的环境部署

day22 回顾 Jenkins 简介 官网Jenkins Jenkins Build great things at any scale The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project. 用来构建一切 其实就是用Java写的一个项目…...

八、鸿蒙开发-网络请求、应用级状态管理

提示&#xff1a;本文根据b站尚硅谷2024最新鸿蒙开发HarmonyOS4.0鸿蒙NEXT星河版零基础教程课整理 链接指引 > 尚硅谷2024最新鸿蒙开发HarmonyOS4.0鸿蒙NEXT星河版零基础教程 文章目录 一、网络请求1.1 申请网络访问权限1.2 安装axios库1.2.1 配置环境变量1.2.2 第二步&…...

经验笔记:Git 中的远程仓库链接及上下游关系管理

Git 中的远程仓库链接及上下游关系管理 1. 远程仓库的链接信息 当你克隆一个远程仓库时&#xff0c;Git 会在本地仓库中记录远程仓库的信息。这些信息包括远程仓库的 URL、默认的远程名称&#xff08;通常是 origin&#xff09;&#xff0c;以及远程仓库中的所有分支和标签。…...

创建wordpress用户访问数据库/网站排名怎么做上去

#所有防火墙规则都放到一个shell脚本里&#xff0c;调整后就执行一遍。 #!/bin/sh #首先先清空所有规则 /sbin/iptables -F #-F: FLASH&#xff0c;清空规则链 #for local /sbin/iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT #或者 /sbin/iptables -A INPUT -…...

深圳网站建设技术/免费软文发布平台有哪些

做公号很久了&#xff0c;听到粉丝问的最多的问题就是&#xff1a;有没有新的完整的项目&#xff0c;因为现在很多流传的项目都太老了&#xff0c;实战意义不是很强。很多程序员每项技术单独拿出来有可能很厉害&#xff0c;例如&#xff1a;springcloud、springboot、redis、ng…...

网站功能设计怎么写/网站推广排名

禁止灵格斯2.7弹出“新奇英语 互动锐词”广告窗口的解决方法 用记事本打开并清空C:\Documents and Settings\Administrator\Application Data\Lingoes\Translator\tip.xml里的内容&#xff0c;保存后改属性为只读。 win7 下的路径是C:\Users\用户名\AppData\Roaming\Lingoes\T…...

怎么访问被禁止的网站/青岛seo网站建设公司

用于接收父组件传入的参数 简易版——数组的方式定义 props: [size, myMessage] 详细版——对象的方式定义 props: {// 限定参数的数据类型必须为字符串code: String, // 限定参数的类型为字符串型&#xff0c;或数值型 Numberparams2: [String, Number],name:{type:String…...

有限公司英文/整站优化seo

1.震动是系统的服务,首先需添加震动权限 <uses-permission android:name"android.permission.VIBRATE" /> 2.实现震动方法代码 public static void sendVibrater(Context mContext) { // 间隔震动Vibrator mVibrator (Vibrator) mContext.getSystemService(m…...

有没有在线做动图的网站/房地产营销策略有哪些

Kubernetes Dashboard 是 k8s集群的一个 WEB UI管理工具&#xff0c;代码托管在 github 上&#xff0c;地址&#xff1a;https://github.com/kubernetes/dashboard #由于镜像无法直接下载需要通过docker 先将镜像拉下来 #拉取镜像docker pull mirrorgooglecontainers/kubernet…...