线上问题:FeignClient循环依赖及源码分析

news2024/9/21 14:32:57

1 场景复现

依赖关系:虚线左侧为实现的类,虚线右侧为Spring的原生接口类或注解。
正常看,没有循环依赖,但是,实际运行时,异常信息:Is there an unresolvable circular reference?
明确告知,可能存在循环依赖,需要进一步从异常日志排查。
在这里插入图片描述

1.1 FeignClient

通过Feign调用服务。
在这里插入图片描述

1.2 HandlerInterceptor

新建Token拦截器。
在这里插入图片描述

1.3 WebMvcConfigurer

添加Token拦截器。
在这里插入图片描述

1.4 Controller

接口依赖FeignClient。
在这里插入图片描述

2 方案

在TokenInterceptor的FeignClient添加@Lazy,启动SpringBoot时不加载TokenInterceptor的FeignClient,当服务启动完成后,有需要时再加载,这样就不用再启动时重复验证单例FeignClient,保证服务正常启动。
在这里插入图片描述

3 分析

SpringBoot启动时堆栈信息如下:从内往外抛出异常,
异常信息较多,分段看。

  • 第一段
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘rpcApi’: Unsatisfied dependency expressed through field ‘feignTemplateService’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration’: Unsatisfied dependency expressed through method ‘setConfigurers’ parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘webMvcHandler’: Unsatisfied dependency expressed through field ‘tokenInterceptor’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tokenInterceptor’: Unsatisfied dependency expressed through field ‘templateService’; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘com.monkey.tutorial.common.rpc.IFeignTemplateService’: Requested bean is currently in creation: Is there an unresolvable circular reference?

  • 第二段
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration’: Unsatisfied dependency expressed through method ‘setConfigurers’ parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘webMvcHandler’: Unsatisfied dependency expressed through field ‘tokenInterceptor’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tokenInterceptor’: Unsatisfied dependency expressed through field ‘templateService’; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘com.monkey.tutorial.common.rpc.IFeignTemplateService’: Requested bean is currently in creation: Is there an unresolvable circular reference?

  • 第三段
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘webMvcHandler’: Unsatisfied dependency expressed through field ‘tokenInterceptor’; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tokenInterceptor’: Unsatisfied dependency expressed through field ‘templateService’; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘com.monkey.tutorial.common.rpc.IFeignTemplateService’: Requested bean is currently in creation: Is there an unresolvable circular reference?

  • 第四段
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘tokenInterceptor’: Unsatisfied dependency expressed through field ‘templateService’; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘com.monkey.tutorial.common.rpc.IFeignTemplateService’: Requested bean is currently in creation: Is there an unresolvable circular reference?

  • 第五段
    Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘com.monkey.tutorial.common.rpc.IFeignTemplateService’: Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-5.3.6.jar:5.3.6]

3.1 定位异常

第五段异常信息可以定位到抛出异常的位置:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation,
这个方法是新建单例对象前的校验,源码如下图所示:
在这里插入图片描述
由源码可知,新建单例对象前都会通过beforeSingletonCreation校验需要创建的单例对象是否在当前集合中,根据源码的判定逻辑,如果需要创建的单例对象名称(beanName)在singletonsCurrentlyInCreation中,则抛出异常。

3.2 调试方案

通过异常定位以及对抛出异常的逻辑分析,
可在beforeSingletonCreation处打断点调试,下面是几个核心位置的调试信息:rpcApi、WebMvcHandler、TokenInterceptor和IFeignTemplateService。

3.2.1 rpcApi

rpcApi校验创建单例对象调试信息如下图所示,
图中右侧,this.singletonsCurrentlyInCreation集合为空,因此,可以通过校验。
在这里插入图片描述

3.2.2 IFeignTemplateService

进入IFeignTemplateService校验,由于rpcApi依赖IFeignTemplateService,
因此,rpcApi校验结束后,会进入IFeignTemplateService校验,
调试结果如下图所示,由图可知,IFeignTemplateService的this.singletonsCurrentlyInCreation已经存在一个元素rpcApi,
即rpcApi依赖IFeignTemplateService,而IFeignTemplateService不在集合singletonsCurrentlyInCreation中,因此校验通过。

在这里插入图片描述

3.2.3 mvcResourceProvider

接下来校验的脚步会被mvcResourceUrlProvider截胡,
先进行mvcResourceUrlProvider校验,
调试结果如下图所示,由图可知,this.singletonsCurrentlyInCreation中已存在rpcApi和IFeignTemplateService,
说明rpcApi和IFeignTemplateService是依赖mvcResourceUrlProvder的,此时,校验通过,
这里的核心是:IFeignTemplateService已经添加到this.singletonsCurrentlyInCreation,是后续抛出异常的引子
在这里插入图片描述

3.2.4 webMvcHandler

mvcResourceUrlProvider依赖webMvcHandler,
mvcResourceUrlProvider校验通过后,会进入webMvcHandler校验,
调试结果如下图所示,由图可知,webMvcHandler校验通过,无异常。
在这里插入图片描述

3.2.5 tokenInterceptor

webMvcHandler依赖tokenInterceptor,校验webMvcHandler后,会进入tokenInterceptori校验,
tokenInterceptor校验过程如下图所示,校验通过。
在这里插入图片描述

3.2.6 IFeignTemplateService

由于tokenInterceptor也依赖IFeignTemplateService,
所以,tokenInterceptor校验通过后,会接着校验IFeignTemplateService,
调试过程如下图所示,综合上面的分析,this.singletonsCurrentlyInCreation中已经存在IFeignTemplateService,
(由于IFeignTemplateService依赖mvcResourceUrlProvider;mvcResourceUrlProvider依赖webMvcHandler)
校验失败,抛出异常。
在这里插入图片描述
抛出异常
在这里插入图片描述

3.3 循环依赖

经过分析,形成的循环依赖如下图所示。

在这里插入图片描述

3.4 解决

为了保证SpringBoot服务,需要打破循环依赖,
所以,在TokenInterceptor中,在服务启动时不加载FeignClieit,
在FeignClient上面添加@Lazy注解,延迟加载,服务启动后,有调用时再加载。
在这里插入图片描述

4 小结

(1)循环依赖有显式依赖:如A->B->C->A,以及隐式依赖,需要逐步调试;
(2)循环依赖的解决方案:断开环,可调整代码设计、延迟加载等方式。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Navidrome - 开源音乐服务器【打造属于自己的音乐播放器】「端口映射」随时随地想听就听

文章目录1. 前言2. Navidrome网站搭建2.1 Navidrome下载和安装2.1.1 安装并添加ffmpeg2.1.2下载并配置Navidrome2.1.3 添加Navidrome到系统服务2.2. Navidrome网页测试3. 本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置4. 公网访问测试5. 结语1. 前言…

十二、市场活动:修改

功能需求 ①、用户在市场活动主页面,选择要修改的市场活动,点击"修改"按钮,弹出修改市场活动的模态窗口; ②、用户在修改市场活动的模态窗口填写表单,点击"更新"按钮,完成修改市场活动的功能. ③、 *每次能且只能修改一条市场活动 ④、*所有者 动态的…

电脑组装教程分享!

案例:如何自己组装电脑? 【看到身边的小伙伴组装一台自己的电脑,我也想试试。但是我对电脑并不是很熟悉,不太了解具体的电脑组装步骤,求一份详细的教程!】 电脑已经成为我们日常生活中不可或缺的一部分&a…

Nginx用作 内网CDN / edge cache 服务

文章目录什么是CDN?为什么需要 内网CDN/edge cache?Nginx配置Edge Cache服务配置简单静态文件缓存服务配置缓存控制$upstream_cache_statusGzip压缩参考什么是CDN? 首先要明白什么是CDN? CDN英文全称Content Delivery Network,…

Springboot基础学习之(十七):通过Shiro实现用户得到登录认证和授权

前几篇文章讲解了关于信息安全的另一框架Spring security ,今天趁热打铁基础的了解以下shiro这一框架。 什么是shiro? Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应…

c++11 标准模板(STL)(std::stack)(二)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack;std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包装…

线索二叉树(前序,中序,后序线索化以及遍历)

其实在这之前我想了很久&#xff0c;这个线索化二叉树我个人感觉是比实现二叉链表要难&#xff0c;很抽象的一个东西。好了&#xff0c;话先不多说&#xff0c;老规矩&#xff0c;先上代码&#xff1a; #pragma once #include<stdio.h> #include<stdlib.h> #inclu…

std::inner_product与std::accumulate初始值设置踩坑

std::inner_product函数可以用于计算两个序列的内积。在这个函数中&#xff0c;我们需要传递四个参数&#xff1a;两个源序列的起始迭代器、一个初始值和一个二元函数对象。 std::inner_product函数将对两个源序列中的每个元素进行乘法运算&#xff0c;并将结果累加到初始值中…

FPGA基于XDMA实现PCIE X4通信方案 提供工程源码和QT上位机程序和技术支持

目录1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PCI …

桥接设计模式解读

目录 问题引进 手机操作问题 传统方案解决手机操作问题 传统方案解决手机操作问题分析 桥接模式(Bridge)概述 基本介绍 原理类图 主要角色 桥接模式解决手机操作问题 桥接模式的注意事项和细节 常见的应用场景 问题引进 手机操作问题 现在对不同手机类型的不同品牌…

Mybatis(七)Mybatis的日志体系

在介绍Mybatis日志实现前&#xff0c;我们先了解下java的日志体系以及日志框架的发展&#xff0c;目前比较常用的日志框架有下面几个&#xff1a; 而JCL和SLF4J属于日志接口&#xff08;没有日志具体实现&#xff09;&#xff0c;提供统一的日志操作规范&#xff0c;而日志的实…

Halo博客建站实战以及问题汇总

目录 简介 特性 快速开始 安装步骤 环境准备 Docker-compose方式部署 问题汇总 mac端无法访问页面 页面登录提示账号密码错误 重装注意点 资料 官方文档 简介 Halo 强大易用的开源建站工具 特性 代码开源 我们的所有代码开源在 GitHub 上且处于积极维护状态&…

stata数据处理

stata数据处理–潘登同学的stata笔记 文章目录stata数据处理--潘登同学的stata笔记数据导入、导出使表格第一行成为变量标注(label)数据合并横向与纵向合并一对多与多对一横向合并缺失值处理查看缺失值替换缺失值缺失值填充离群值处理取对数的方法截尾处理、缩尾处理分组统计列…

银行数字化转型导师坚鹏:银行数字化转型痛点、路径与对策

银行数字化转型痛点、路径与对策课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不知道银行数字化转型&#xff1f; 不清楚数字化转型对银行发展有什么影响&#xff1f; 不知道数字化转型对银行有什么机遇&#xff1f; 学员收获: 学习银行数字化转型的发展现状与成…

2021四川省icpc省赛H题 Nihongo wa Muzukashii Desu 日本語は難しいです!

日本語は難しいです&#xff01; それは難しくないと思うだけど 传送门 一些吐槽 这题好像恶心了不少学弟啊 其实只要读懂了题就很好做, 对于我这种日语高考生来说确实是有点犯规了不过当时我写的时候不能用翻译一看题面一大串英文就被我pass掉, 后面看到一大堆人过了我才去写…

迅为RK3568开发平台人工智能人脸识别全国产解决方案赋能NVR

人脸识别服务&#xff0c;能够在图像中快速检测人脸、分析人脸关键点信息、获取人脸属性、实现人脸的精确比对和检索。可应用于身份验证、电子考勤、客流分析等场景人脸检测、比对、搜索&#xff0c;人脸库管理等。 为什么使用它呢&#xff1f; 维持公众聚集场所的秩序 在餐厅…

Apache的配置与运用

1. web虚拟主机的构建 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务器&#xff0c;因此被称为“虚拟”Web 主机。通过虚拟 Web 主机服务可以充分利用服务器的硬件资源&#xff0c;从而大大降低网站构建及运行成本。…

2.3.2 单链表的插入结点操作

--单链表示意图 一、按位序插入&#xff08;带头结点&#xff09; ①表头插入 注意点 1.i1&#xff0c;while循环不执行 2.时间复杂度为O&#xff08;1&#xff09; 3.p&#xff01;NULL表示指针p有指向结点 4.头结点为第0个结点 5.pL表示指针p和L指向位置相同&#xff0…

ORB_SLAM3_优化方法 Pose优化

PoseOptimization PoseOptimization主要的作用是利用重投影优化单帧的位姿,主要用在Tracking的几种跟踪模式TrackWithMotionModel、TrackReferenceKeyFrame、 TrackLocalMap、Relocalization中 输入 优化变量观测帧的Pose帧的MapPoint帧的KeyPoint初始化 //创建优化器 g2o…

4.Java逻辑控制语句

Java逻辑控制语句 在实际生活中&#xff0c;我们的生活不是一成不变的&#xff0c;很多时候需要我们去选择&#xff0c;大到人生的十字路口&#xff0c;小到今天晚上吃什么&#xff0c;选择无处不在。小的选择决定了我们一件小事的走向&#xff0c;大的选择可能会改变我们人生…