BeanCurrentlyInCreationException: Error creating bean with name 'TestService1':
Requested bean is currently in creation: Is there an unresolvable circular reference?
解决办法一(简单直接快捷):
- 从报错信息中可以得到报错信息的类,比如上面的TestService1,那么就先找到TestService1这个类。
- 查看一下它依赖的bean,看一看是哪个bean产生了循环调用。可以直接点进去一层一层的看,也可以通过最近修改,依赖较深的时候可以通过注释掉不同的类来判断。
- 然后判断TestService1是注解依赖注入还是构造方法注入
- 假设和它冲突的bean是TestService2
- 如果是构造方法注入,那么先改成依赖注入,启动查看是否报错
- 如果执行了步骤四还是报错,或者一开始就是注解依赖注入,那么在依赖的bean上面或者是构造方法中bean的参数上加上**@Lazy**注解,延迟一下它的加载顺序即可。
解决办法二
解决办法一解决了问题,但是只是最直接的,还可以进一步的探索问题发生的原因。
比如有的人会这么想,构造方法注入产生循环依赖我可以理解,但是使用注解依赖注入怎么还会循环依赖呢?spring不是解决了循环依赖么?
那么请检查以下几项
- 报错的bean中,是不是有**@Async**异步方法?如果是,那么把这个方法拿到别的bean再试试。
- 请检查你是不是给某些bean改成了多例模式?比如**@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)**,如果是请改成单例
- 请检查报错的bean是不是使用了**@DependsOn**注解,如果是的话,请去掉。
解决办法三
还有一种个人最推荐的办法,特别是项目初期。
-
首先,全部使用构造器注入(甚至idea都会提示你)
固然,使用依赖注入会帮我们解决大部分的依赖冲突问题,但是这也导致了我们的代码设计会很乱,没有层次性。
当你的代码出现了循环依赖,那就证明设计上或多或少存在一些问题了。
使用构造器注入能够保证你的代码一旦有循环依赖,能够及时发现。 -
其次,当出现了循环依赖后,怎么解决呢?首先建议把导致循环引用的方法好好审查一下
- 这个方法放在这个bean里是不是合适?
- 要不要把方法抽象到第三个bean,大家一起使用?
- 不影响事务的话能不能够放在controller?比如不涉及增删改的操作。
- 业务层里是不是能够直接调用持久层?比如查单表的方法。
- 都没问题的话,是不是表的设计有问题?
当然不止这些点,如果能够从设计层面解决循环依赖,那你的代码设计和结构设计一定是相对完美的。
-
最后,如果是祖传代码,建议还是别这么搞了,使用方法一和方法二即可。