一、序言

SpringBoot 2.6.x不推荐使用循环依赖,这是一个好消息,SpringBoot从底层逐渐引导开发者书写规范的代码,同时也是个忧伤的消息,循环依赖的应用场景实在是太广泛了。

如果从低版本升级到2.6.x,那么很大概率遇到的第一个问题便是循环依赖问题。

二、问题复原

1、代码说明

下面风格的代码比较普遍:两个类都有调用对方方法的需求,因此很容易写成循环引用。

@Service
public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService { @Autowired
private ITbStaffService staffService;
}

@Service
public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService {
@Autowired
private ITbDeptService deptService;
}
2、错误示例
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

Despite circular references being allowed, the dependency cycle between beans could not be broken. Update your application to remove the dependency cycle.

三、问题解决

1、粗暴解决

最简单的方式是在全局配置文件中允许循环引用存在,此属性默认值为false,显示声明为true,可回避项目启动时控制台循环引用异常。

spring:
main:
allow-circular-references: true
2、优雅解决

Spring官方默认禁止使用循环依赖,尽管留有可选配置,允许开发者继续使用循环依赖。

Spring官方的初心是不希望开发者编写循环依赖的代码,也就是说未来的某个版本可能强制不得使用循环依赖,因此逐渐在新项目中消除循环依赖是不得不面对的问题。

使用方法的返回值获取实例对象,替换通过成员变量注入实例对象。

@Service
public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService {
/**
* 使用方法返回实例对象,替换成员变量注入
* @return ITbStaffService
*/
public ITbStaffService getStaffService(){
return SpringUtils.getBean(ITbStaffService.class);
}
}
@Service
public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService {
/**
* 使用方法返回实例对象,替换成员变量注入
* @return ITbStaffService
*/
public ITbDeptService getDeptService(){
return SpringUtils.getBean(ITbDeptService.class);
}
}

其中需要使用如下依赖,此依赖是笔者抽离出来的公共依赖,可跨项目使用。

<dependency>
<groupId>xin.altitude.cms.common</groupId>
<artifactId>ucode-cms-common</artifactId>
<version>1.3.4</version>
</dependency>

如果找不到此依赖,很大可能是阿里云Maven仓库尚未同步,在项目中强制使用Maven中央仓库即可。

<repositories>
<repository>
<id>public</id>
<name>maven nexus</name>
<url>https://repo1.maven.org/maven2/</url>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>

四、小结

Spring生态作为广泛使用的框架,俨然成为Java企业级应用主流标准,其微小的变化对整合生态带来不可估量的影响。从跟随者转化为引导者,果断禁止循环依赖问题,体现的是作为引导者的担当。

循环引用使用习惯了,初步看起来代码没毛病,仔细想想是不合理的设计。循环依赖的直接表现是你中有我,我中有你,从对象的设计上令人费解。

最为开发者时刻关注底层框架的变动,将会在应用层收益。这里所说的底层框架是指JDK、Spring生态、Apache、知名大厂开源并广泛被应用的框架,比如guava等。

最新文章

  1. VR ( Virtual Reality )、AR(Augmented Reality)、MR(Mix Reality)和CR(Cinematic Reality)是什么鬼?
  2. Self-introduction (自我介绍)
  3. 033医疗项目-模块三:药品供应商目录模块——供货商药品目录t添加查询功能----------Dao层和Service层和Action层和调试
  4. (转) Docker swarm 之介绍与使用
  5. 面试求职中需要了解的Java多线程知识
  6. CodeForces 362B Petya and Staircases
  7. -_-#flash播放器自适应
  8. Oracle10g数据泵EXPDP和IMPDP备份与恢复数据
  9. P/Invoke与逆向P/Invoke
  10. 利用canvas制作乱跑的小球
  11. Redis基本数据类型
  12. Java 核心内容相关面试题【1】
  13. bootstrap栅格布局学习历程
  14. Asp.net mvc 中的 Controller 的激活
  15. SpringBoot: 配置加载顺序
  16. Windows 10无法连接远程桌面解决办法(这可能是由于CredSSP加密Oracle修正)
  17. Python实现图像直方图均衡化算法
  18. Windows操作系统下搭建Git服务器和客户端。
  19. 下载安装Emacs和基本配置--待更新中
  20. Python实现快速排序--数据结构

热门文章

  1. 【刷题-LeetCode】210. Course Schedule II
  2. gin中XML/JSON/YAML/ProtoBuf 渲染
  3. Android开发----Button组件的使用与练习
  4. electron-vue 项目添加启动loading动画问题
  5. 阿里巴巴发布最佳实践 | 阿里巴巴DevOps实践指南
  6. python 中 *args he **kwargs的区别
  7. ABC222 部分简要题解
  8. (DDS)正弦波形发生器——幅值、频率、相位可调(一)
  9. JQuery扩展方法实现Form表单与Json互相转换
  10. java中使用反射获取pojo(实体)类的所有字段值