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

Spring循环依赖

Spring循环依赖

  • 问题及日志
  • 问题代码截图
  • 解决方案
    • 使用@Lazy延迟加载
    • 重构代码结构
    • 本次问题解决
  • 相关问题及解释
  • 参考资料

问题及日志

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2025-05-21 09:05:55.193 DEBUG 1 --- [           main] o.h.c.a.Slf4jFailureAnalysisReporter     : Application failed to start due to an exceptionorg.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration': Requested bean is currently in creation: Is there an unresolvable circular reference?中间日志省略2025-05-21 09:05:55.194 ERROR 1 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : ***************************
APPLICATION FAILED TO START
***************************Description:The dependencies of some of the beans in the application context form a cycle:dataChangeAdvice defined in URL [jar:file:/inja-demand.jar!/BOOT-INF/classes!/com/inja/demand/record/aspect/DataChangeAdvice.class]
┌─────┐
|  org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
↑     ↓
|  attachmentLogInterceptor (field private com.inja.demand.record.domain.repository.ChangeLogRepository com.inja.demand.requirement.interceptor.AttachmentLogInterceptor.changeLogRepository)
↑     ↓
|  changeLogRepositoryImpl (field private io.choerodon.mybatis.common.BaseMapper io.choerodon.mybatis.service.BaseServiceImpl.mapper)
↑     ↓
|  changeLogMapper defined in URL [jar:file:/inja-demand.jar!/BOOT-INF/classes!/com/inja/demand/record/infra/mapper/ChangeLogMapper.class]
└─────┘

问题代码截图

在这里插入图片描述
在这里插入图片描述

解决方案

使用@Lazy延迟加载

在其中一个依赖项上添加@Lazy注解来打破循环,例如在AttachmentLogInterceptor的字段注入处:

public class AttachmentLogInterceptor {@Lazy@Autowiredprivate ChangeLogRepository changeLogRepository;
}

不建议使用该方案,因为发生循环依赖本质是代码设计不合理,
要从根本上解决问题,重构代码。

重构代码结构

注意不适用本次出现的问题

  1. 检查是否可以将部分依赖关系改为构造函数注入

    import org.springframework.beans.factory.annotation.Autowired;public class AttachmentLogInterceptor implements Interceptor {private final ChangeLogRepository changeLogRepository;// 构造函数注入@Autowired // 如果只有一个构造函数,可以省略这个注解public AttachmentLogInterceptor(ChangeLogRepository changeLogRepository) {this.changeLogRepository = changeLogRepository;}// 其他方法保持不变...
    }
    
  2. 考虑将某些通用功能抽离到独立的工具类中

  3. 检查BaseServiceImpl的mapper注入方式

本次问题解决

根据代码分析,DataChangeAdvice 通过构造函数直接依赖 SqlSessionTemplate 和 MapperHelper,
而 SqlSessionTemplate 的创建依赖 MyBatis 自动配置(MybatisAutoConfiguration),最终形成以下循环链:DataChangeAdvice → SqlSessionTemplate → MybatisAutoConfiguration → (其他拦截器/组件) → DataChangeAdvice

修改代码:延迟依赖初始化(核心思路)

@Aspect
@Component
@Slf4j
public class DataChangeAdvice {// 关键点:使用 ObjectProvider 延迟获取 SqlSessionTemplateprivate final ObjectProvider<SqlSessionTemplate> sqlSessionTemplateProvider;private final ObjectProvider<MapperHelper> mapperHelperProvider;// 构造函数改造:不再直接依赖 SqlSessionTemplatepublic DataChangeAdvice(ObjectProvider<SqlSessionTemplate> sqlSessionTemplateProvider,ObjectProvider<MapperHelper> mapperHelperProvider) {this.sqlSessionTemplateProvider = sqlSessionTemplateProvider;this.mapperHelperProvider = mapperHelperProvider;}// 实际使用时再获取依赖(例如在切面方法中)@Around("@annotation(yourAnnotation)")public Object handleDataChange(ProceedingJoinPoint joinPoint) throws Throwable {SqlSessionTemplate sqlSession = sqlSessionTemplateProvider.getObject();  // 按需获取MapperHelper helper = mapperHelperProvider.getIfAvailable();// 业务逻辑...return joinPoint.proceed();}
}

相关问题及解释

在这里插入图片描述

参考资料

https://blog.csdn.net/qq_27759825/article/details/129027330

http://www.xdnf.cn/news/7936.html

相关文章:

  • 从版本控制到协同开发:深度解析 Git、SVN 及现代工具链
  • 六台升降台完整的限位保护逻辑
  • springboot3.x只需两步快速整合nacos作配置中心
  • NSSCTF [BJDCTF 2020]YDSneedGirlfriend
  • 深度图转换为点云文件脚本
  • 2025-05-21 Python深度学习5——数据读取
  • 深入解析应用程序分层及 BaseDao 的封装策略
  • Electron 后台常驻服务实现(托盘 + 开机自启)
  • 第18天-NumPy + Pandas + Matplotlib多维度直方图
  • HashMap 两数之和java
  • 【最细】自动化测试-解决日志问题,一文贯通...
  • 深入浅出IIC协议 - 从总线原理到FPGA实战开发 --第四篇:I2C工业级优化实践
  • 2024CCPC辽宁省赛 个人补题 ABCEGJL
  • Plant Cell|澳大利亚国立大学研究团队揭示狗尾草应对长期高温的 “生存秘籍”-三重协同机制逆天改命!
  • 46页 @《人工智能生命体 新启点》中國龍 原创连载
  • fatload使用方式
  • 解锁 YOLOv8 新潜能:EfficientViT 主干网络的优化实践与实验数据解读
  • 【spring】spring学习系列之十一:spring的事件监听
  • uni.getLocation()和uni.openSetting()
  • SOC-ESP32S3部分:5-IDF的日志管理
  • LVDS系列13:Xilinx Ultrascale系可编程输入延迟(三)
  • STM32之串口通信WIFI上云
  • Centos8安装 python3并保留系统的python2
  • C语言求1到n的和(附带源码和解析)
  • 华为云Flexus+DeepSeek征文|零基础搭建Dify-LLM应用开发平台 - 从部署到应用的完整指南
  • 关于光谱相机的灵敏度
  • C++学习之类和对象_2
  • 【web全栈】若依框架B站学习视频
  • 面向高温工业场景的EtherCAT/CANopen协议转换系统设计与应用
  • 互联网大厂Java求职面试:Spring Cloud微服务架构与AI集成挑战