章
目
录
最近在开发Java项目的过程中发现了一个循环依赖问题需要解决,而这个循环依赖产生的原因就是在spring中使用@Autowired
注解注入导致的,一般这样的循环依赖很难通过人工查找发现,很多情况是在项目联调测试或者发布启动的时候会在日志中打印出来才被发现,也可能在本地运行没问题,在服务器打包就出错,可能这次打包没错,下次打包就有错了,只要有一次出错了,就说明存在该问题。
问题描述
比如我的这个循环依赖报出如下描述:
The dependencies of some of the beans in the application context form a cycle:
electionListener (field private com.sf.hlcs.sda.service.OpcAllocationService com.sf.hlcs.sda.election.listener.ElectionListener.opcAllocationService)
┌─────┐
| opcAllocationServiceImpl (field private com.sf.hlcs.sda.election.registry.ServerRegistry com.sf.hlcs.sda.service.impl.OpcAllocationServiceImpl.serverRegistry)
↑ ↓
| serverRegistry (field private com.sf.hlcs.sda.election.listener.NodeListener com.sf.hlcs.sda.election.registry.ServerRegistry.listener)
↑ ↓
| nodeListener (field private com.sf.hlcs.sda.service.OpcAllocationService com.sf.hlcs.sda.election.listener.NodeListener.opcAllocationService)
└─────┘
从上述提示代码可以发现,这里出现的循环依赖是:opcAllocationServiceImpl
实体依赖serverRegistry
实体,而serverRegistry
实体依赖nodeListener
实体,而nodeListener
实体却又依赖opcAllocationServiceImpl
实体,这就形成了一个循环依赖的结果。
看下简要代码
// 第一部分 @Service public class OpcAllocationServiceImpl implements OpcAllocationService { @Autowired private ServerRegistry serverRegistry; // 省略.... } // 第二部分 @Component public class ServerRegistry { @Autowired private NodeListener listener; // 省略.... } // 第三部分 @Component public class NodeListener implements Listener { @Autowired private OpcAllocationService opcAllocationService; // 省略.... }
通过代码发现,确实出现了循环依赖。
解决办法
我这里的解决办法其实就是将其中的任何一层依赖断开即可,这里我是通过借助了另外一个discovery
类来替换了OpcAllocationService
类中对ServerRegistry
的依赖,通过discovery
类也能实现ServerRegistry
的部分功能,而这部分功能在OpcAllocationService
类中已经够用,所以就断开了他们的依赖,从而也解决了循环依赖的问题,当然还有很多其他办法,我这个比较巧的是,正好有其他类可以代替,如果没有其他类代替怎么办?更多的方法请参考:
文章目录一、什么是循环依赖 二、怎么判断产生了循环依赖 三、3种循环依赖的情况 四、Spring循环依赖如何解 […]