Java项目中启动报错循环依赖问题解决

createh52个月前 (03-04)技术教程19

项目启动时候失败,有时候经常看到这样的错误信息:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: 
Error creating bean with name 'liveRoomServiceImpl': Bean with name 'liveRoomServiceImpl' 
has been injected into other beans [rongCouldMsgService] 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 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

出现类似的情况,说明就是循环依赖所导致的了。

常见的会导致循环依赖出现的编程方式

项目中常见的就是service层那一块会出现错误的引用方式导致出现循环依赖:

项目中存在bean自己引用自己的情况

@Service
public class TestServiceImpl implements TestService {
 Logger logger = LoggerFactory.getLogger(TestServiceImpl.class);
 @Autowired
 TestService testService;
 @0verride
 @Async
 public void test(){
     System. out.println(1122) ;
 }
}


项目serviceA引用serviceB,serviceB中有引用serviceA的情况

@Service
public class LiveAttentionServiceImpl extends BaseService implements LiveAttentionService {

    @Autowired
    private LivePanelService livePanelService;
}
public class LivePanelServiceImpl implements LivePanelService {

    @Autowired
    private LiveAttentionService liveAttentionService;

}

以上这两种写法都会导致循环依赖的问题,最终导致在项目中启动时候出现如上错误信息。

解决方案

Spring循环引用报错,目前没有很好的解决方案

in its raw version as part of a circular reference, but has eventually been wrapped.

循环依赖Spring是解决的,得益于spring的内部机制,让我们根本无法感知它有问题,因为spring默默帮我们解决了,使用的是内部有三级缓存:

  • singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
  • earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例singletonFactories
  • 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。

但是为什么还会出现呢?可能是循环依赖写法导致Spring三级缓存也没法注入正确导致。有如何解决方案。

1. 使用@Lazy注解,延迟加载进行解决

@Lazy注解的功能是,在Spring 在启动的时候延迟加载这个bean,然后在他即调用这个bean的时候再去初始化,这样就避免了Spring循环引用的异常。

2. 避免这种写法

业务中非得使用ServiceA注入ServiceB,ServiceB中注入ServiceA的业务场景,则抽取出来一个ServiceAB类,在ServiceAB中注入ServiceA和ServiceB

3. 使用SpringUtils工具类获取实例化循环依赖的Bean

和@Lazy有异曲同工之处

循环依赖原因

相关文章

解决maven依赖冲突,这篇就够了

一、前言什么是依赖冲突依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突。依赖冲突的原因我们在maven项目的pom中 一般会引用许许多多的dependency。例如,项目A...

Java:Spring用三级缓存解决循环依赖问题

缓存其实就是三个Map容器:singletonObjects, 一级缓存;earlySingletonObjects, 二级缓存;singletonFactories 三级缓存。如下图例如:A引用B...

大厂面试必问之Spring的循环依赖

面试的重点,大厂必问之一:循环依赖1. 什么是循环依赖看下图image.png??上图是循环依赖的三种情况,虽然方式有点不一样,但是循环依赖的本质是一样的,就你的完整创建要依赖与我,我的完整创建也依赖...

彻底搞懂Spring依赖注入(一)Bean实例创建过程

上一章介绍了Bean的加载过程(IOC初始化过程),加载完成后,紧接着就要用到它的依赖注入(IOC 依赖注入)。那什么是依赖注入呢?所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到...

简单2步实现maven打包java工程并将依赖jar输出到指定目录

最近由于为了验证的需要,在本地使用maven打包时需要将工程依赖的jar同步输出到指定文件夹, 通过验证,将此方法分享给大家1. pom文件中引用如下2个插件 org.apache.maven.p...