Spring Bean的循环依赖The dependencies of some of the beans in the application context form a cycle解决记录

事情起因

  • 很久没有遇见循环依赖的问题了,起早上班启动准备和前端联调就报这个问题,大概率是昨天同事写的代码没有启动测试(所以啊,在提交代码前还是得自己启动下测试过才提交,避免影响他人)

问题出现

  • 启动报错:The dependencies of some of the beans in the application context form a cycle
***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   memberCenterController (field private SysUserService MemberCenterController.userService)
┌─────┐
|  sysUserServiceImpl defined in file [SysUserServiceImpl.class]
↑     ↓
|  distributionRegisteredServiceImpl (field private DistributeMemberService DistributionRegisteredServiceImpl.memberService)
↑     ↓
|  distributeMemberService (field private DistributeMemberTagServiceImpl DistributeMemberService.memberTagService)
↑     ↓
|  distributeMemberTagServiceImpl (field private SysUserServiceImpl DistributeMemberTagServiceImpl.userService)
└─────┘



Process finished with exit code 1

问题分析

这是一个十分常见的循环依赖问题,就算没有遇见过看着箭头指来指去的,也会往循环依赖问题靠一靠。
我看到产生循环依赖的类是从SysUserServiceImpl开始的 我就去看了下SysUserServiceImpl类用的构造方法注入
Spring Bean的循环依赖The dependencies of some of the beans in the application context form a cycle解决记录_第1张图片

循环依赖实质:

  • 类A需要通过构造函数注入的类B的实例(或者B中声明的Bean),而类B需要通过构造函数注入的类A的实例(或者A中声明的Bean)。如果将类A和类B的bean配置为相互注入,则Spring IoC容器会在运行时检测到此循环引用,并引发一个BeanCurrentlyInCreationException。与典型情况(没有循环依赖)不同,bean A和bean B之间的循环依赖关系迫使其中一个bean在被完全初始化之前被注入到另一个bean中。Spring也解决不了到底是先有鸡还是先有蛋的问题了。

解决方案

方法一:

  • 不使用基于构造函数的依赖注入
  • 在字段上使用@Autowired注解,让Spring决定在合适的时机注入。【推荐】
  • 用基于setter方法的依赖注射取代基于构造函数的依赖注入来解决循环依赖。
  • 在@Autowired注解上方加上@Lazy注解(延迟加载)
@Lazy
@Autowired
private SysUserServiceImpl userService;

方法二:

  • 使用SpringContextHolder获取已经存在的bean
SysUserServiceImpl  userService= SpringContextHolder.getBean(SysUserServiceImpl .class)

如有其他解决方式或者见解欢迎留言交流!

你可能感兴趣的:(问题王,spring)