java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot循环依赖

SpringBoot3.x循环依赖问题解决方案

作者:陌路

这篇文章主要介绍了SpringBoot3.x循环依赖的相关知识,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

问题说明

SpringBoot3.x版本已经发布,从SpringBoot2.6.x后就做了很多的改变。

用过SpringBoot2.7.5~x版本的伙伴应该会发现,SpringBoot项目中如果存在循环依赖关系,则在启动项目的时候会出现异常错误信息,提示内容大致为:项目中存在循环依赖,项目无法正常启动运行。

SpringBoot2.7.5~x版本以后至SpringBoot3.x都存在这个问题,Spring已经摒弃循环依赖的问题,需要开发人员自行解决,或在开发过程中尽量避免循环依赖的出现。

对于旧版本项目升级的来说,这将会是一件很棘手的问题,所有的存在循环依赖关系的代码都需要重新调整,况且一不小心就会代码崩溃无法运行。

解决方案

第一种、开启循环依赖(不推荐)

Spring默认已经不在支持循环依赖,在配置文件中重新开启循环依赖支持

spring:
    main:
        allow-circular-references:true #允许循环引用

第二种、懒加载

@Lazy:配合使用该注解可以解决循环依赖问题(在需要注入Bean的地方加上该注解)

@Lazy // 使用懒加载
@Autowired
private OneService oneService;

第三种、控制反转

@Service
@RequiredArgsConstructor // 该注解的使用在下面会有介绍和说明
public class OneServiceImpl implements OneService {
    private final ConfigurableListableBeanFactory beanFactory;
    //代替循环依赖
    public TwoService getTwoService(){
        return beanFactory.getBean(TwoService.class);
    }
}

使用getTwoService() 直接从bean工厂里面去拿对应的Bean来使用

@Service
@RequiredArgsConstructor // 该注解的使用在下面会有介绍和说明
public class TwoServiceImpl implements TwoService {
    private final ConfigurableListableBeanFactory beanFactory;
    //代替循环依赖
    public OneService getOneService(){
        return beanFactory.getBean(OneService.class);
    }
}

以上代码中,OneService依赖于TwoService,而TwoService也依赖于OneService,从而产生循环依赖
解决:每次使用的时候就去Bean工厂里去获取,这样就不存在循环依赖了

@RequiredArgsConstructor使用说明

@RequiredArgsConstructor:该注解是由Lombok提供,可以解决掉大量重复的@Autowired代码
注意:使用@RequiredArgsConstructor时,需要使用final关键字
写在类上可以代替@Autowired注解,需要注意的是在注入时需要用final定义,或者使用@notnull注解

@RestController
@RequiredArgsConstructor // 代替@Autowired注解
@RequestMapping("/api/v1/one")
public class OneController{
	private final OneService oneService; // 需要final关键字
	private final TwoService twoService; // 需要final关键字
	@GetMapping("{id}")
	public ResultVo<String> getDetails(@PathVariable("id") Long id){
		return ResultVo.ok(oneService.getDetailsById(id));
	}
}

注意点:

1、必须声明的变量为final。
2、根据构造器注入的,相当于容器调用带有一组带有参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。基于构造方法为属性赋值,容器通过调用类的构造方法将其进行依赖注入。
3、当需要注入Bean的时候可以直接在类名称上使用@RequiredArgsConstructor,从而代替了大量的@Autowrited注解。

到此这篇关于SpringBoot3.x循环依赖的文章就介绍到这了,更多相关SpringBoot循环依赖内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文