解决org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 问题

Posted 沛沛老爹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决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、要想同样的问题不重复,就有一定的必要去深究背后的问题:

包括是什么原因导致的问题产生;

中间解决的思路是什么(有哪些解决方案,哪个最优);

后续的话在此处要避免哪些和此类似的坑,以免后人复哀后人的情况存在。

开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系

以上是关于解决org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot BigQuery 数据源连接

Spring核心技术之IOC容器:IOC容器与Bean简介

以 # 开头的行不被视为 H2 中 MySQL 的注释

jedis:exception is java.lang.VerifyError: Bad type on operand stack

VS2005中的生成解决方案, 清理解决方案是啥意思?

云原生景观:可观察性和分析解决了什么问题?如何解决的?