解决org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 问题
背景
今天在合并代码,进行打包的时候,突然发现代码跑步起来了。
把错误日志拉出来一看,好家伙,错误日志打印一大堆的
"timestamp":"2022-05-23 22:30:47.544",
"level": "ERROR",
"thread": "main",
"class": "o.springframework.boot.SpringApplication",
"message": "Application run failed" }
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contentAspect': Unsatisfied dependency expressed through field 'topicService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'topServiceImpl': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'storeOrderService';
...
根据错误的反馈信息来看,应该是在初始化bean的时候,直接出错了。
然后每个Service里面又调用了其他的service。就导致了雪崩式的错误信息输出了。
还好代码是走的快速集成的模式。
把错误之前的代码和错误之后的代码进行了一个对比。
发现只有一个地方的代码的变动可能导致了这个问题。
问题定位
根据个人习惯,先把导致出错的代码找出来,比对下代码。
修改前代码
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityDao, ActivityEntity> implements ActivityService {
private final CorrelationService correlationService;
private final RecordService recordService;
public ActivityServiceImpl(CorrelationService correlationService,
RecordService recordService) {
this.correlationService = correlationService;
this.recordService = recordService;
}
...
修改后代码
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityDao, ActivityEntity> implements ActivityService {
private final CorrelationService correlationService;
private final RecordService recordService;
private final OrderService orderService;
public ActivityServiceImpl(CorrelationService correlationService,
RecordService recordService,
OrderService orderService) {
this.correlationService = correlationService;
this.recordService = recordService;
this.orderService = orderService;
}
...
发现两处的代码只是多了一个service的初始化。
注:这个方式的初始化是IDEA的推荐方案。
按照正常来讲,应该是不会出现问题的。
但是既然有问题了,就把错误信息再仔细捋一遍(说实话,英语不好看起来确实比较费力,还好中间循环的Error creating bean with name相关的都可以省略,直接跳到后面错误相关和建议部分。
....
Bean with name 'orderServiceImpl' has been injected into other beans [ActivityServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped.
This means that said other beans do not use the final version of the bean.
This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.
这段错误的相关信息引起了注意。
Bean with name 'orderServiceImpl' has been injected into other beans [ActivityServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped
按照这个说法来讲,orderServiceImpl已经被ActivityServiceImpl霸占了身子(被注入),同时是作为循环引用的一部分。
问题解决
循环引用,那这个问题就简单了。
对于循环引用的解决办法,那都是小儿科的工作了。
解决方案1:拆分
把原来的循环引用的部分拆解出来,让两个servie不再循环引用就可以了。
解决方案2:用回Spring的方案
spring在一般情况下,是帮我们解决了循环依赖的问题的。
但是上面的情况,是没有使用spring的情况。
所以就需要我们自己去判读代码是否会循环依赖。
解决思路比较简单,把构造函数干掉,直接使用@Autowried ,再加个@Lazy就双保险了。
注意如果代码中使用了@Ansyc的话,spring可能没有办法自动解决循环依赖的问题。
具体可以参考下这篇文章
解决方案3:使用单例方式
就是使用static方法的方式来判断当前对象是否已经存在。
如果不存在new个出来。因为唯一,所以就不会有这些麻烦事
总结
1、出问题了,最快的办法是把出问题之前和出之后的对比下,先找到问题解决它,工作上能力很重要,但是老板看重的是你解决问题的能力。
2、要想同样的问题不重复,就有一定的必要去深究背后的问题:
包括是什么原因导致的问题产生;
中间解决的思路是什么(有哪些解决方案,哪个最优);
后续的话在此处要避免哪些和此类似的坑,以免后人复哀后人的情况存在。
转载请注明:解决org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 问题 | 胖虎的工具箱-编程导航