首页 > 其他分享 >springboot2.6开始禁止循环依赖了

springboot2.6开始禁止循环依赖了

时间:2024-02-27 14:56:36浏览次数:18  
标签:springboot2.6 禁止 Spring 依赖 线程 引用 fun main 循环

参考文章: https://mp.weixin.qq.com/s?__biz=MzI0MTUwOTgyOQ==&mid=2247497189&idx=1&sn=0f03cdafad9bacef66c64a490b85ff23&scene=21#wechat_redirect

使用了SpringBoot2.6及以上版本的,如果要允许循环依赖,可以作如下设置 :

方案二:允许循环引用

此方案更像是绕过问题而非解决问题本身!!!

它是一种妥协方案而非最佳实践。在Spring Boot 2.6.0之前版本无需担心此问题(默认允许循环引用),若你准备使用2.6.x但现实情况依旧必须允许循环引用那该怎么办呢?

有哪些现实情况呢?诸如:老项目升级Spring Boot版本需要保持向下兼容性;公司coder的水平不一,强制高标准的要求将会严重影响到生产效率等等

为此,做法只有一个:禁用默认行为(允许循环引用)。具体做法也很简单,其实在文上启动失败的报错详情里Spring Boot已非常贴心的告诉你了:图片所以只需在配置文件application.properties里加上这个属性:

spring.main.allow-circular-references = true

再次启用Spring Boot 2.6.0版本的应用:正常启动。

除了加属性这个方法之外,也可以通过启动类API的方式来设置,能达到同样效果:

public static void main(String[] args) {
    new SpringApplicationBuilder(Application.class)
            .allowCircularReferences(true) // 允许循环引用
            .run(args);
}

图片我们知道,允许循环引用与否其实是Spring Framework的能力,Spring Boot只是将其暴露为属性参数方便开发者来控制而已。那么问题来了,如果是一个构建在纯Spring Framework上的应用,如何禁止循环引用呢?你知道怎么做吗?欢迎在留言区讨论作答,或私聊我探讨学习~


加餐:允许循环引用了但依旧报错

也许你一直认为Spring已经解决循环引用问题了,所以在使用过程中可以“毫无顾忌”。非也,某些“特殊”场景下可能依旧会碰壁,并且问题还很隐蔽不好定位,不信你看我层层递进的给你描述这个场景:

说明:以下代码在允许循环引用的Spring Boot场景下演示运行

基础代码:

本例使用@PostConstruct来模拟触发方法调用,效果和Controller里调Service方法一样哈

@Service
public class AService {

    @PostConstruct
    private void init() {
        String threadName = Thread.currentThread().getName();
        System.out.printf("线程号为%s,开始调用业务fun方法\n", threadName);
        fun();

    }

    public void fun() {
        String threadName = Thread.currentThread().getName();
        System.out.printf("线程号为%s,开始处理业务\n", threadName);
    }

}

启动应用即触发动作,控制台输出为:

线程名为main,开始调用业务fun方法
线程名为main,fun方法开始处理业务

完美!此时,你发现fun方法执行时间太长,需要做异步化处理。你就立马想到了使用Spring提供的@Async注解轻松搞定:

@Async
public void fun() {
 ...
}

再次运行,控制台输出:

线程名为main,开始调用业务fun方法
线程名为main,fun方法开始处理业务

what?木有生效呀!这时你灵机一动,原因是没用开启该模块嘛。所以你迅速的使用@EnableAsync注解启用Spring的异步模块,满怀期待的再次运行应用,控制台输出:

线程名为main,开始调用业务fun方法
线程名为main,fun方法开始处理业务

what a ...?怎么还是不行。你挠了挠头,想起来之前踩过的“事务不生效的坑”,场景和这类似,所以你模仿着采用了相同的方式来解决:自己注入自己(循环依赖)

@Autowired
private AService aService; // 自己注入自己

@PostConstruct
private void init() {
 ...
    aService.fun(); // 通过代理对象调用而非this调用

}

这次满怀信心的再次运行,没想到,启动抛出BeanCurrentlyInCreationException异常

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'AService': Bean with name 'AService' has been injected into other beans [AService] 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.
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:649) ~[spring-beans-5.3.13.jar:5.3.13]
 ...

异常关键字:circular reference循环引用!!!不是说好了允许循环引用的吗?怎么肥四?怎么破???

至此,笔者将此问题抛出,有兴趣的同学可思考一下问题根因、解决方案哈。最终的效果应该是不同线程异步执行的:

线程名为main,开始调用业务fun方法
线程名为task-1,fun方法开始处理业务

Tips:笔者在之前的文章里对此问题有过非常非常详细的叙述,感兴趣的可自行向前翻哈!!!主动学习

标签:springboot2.6,禁止,Spring,依赖,线程,引用,fun,main,循环
From: https://www.cnblogs.com/joeblackzqq/p/18036871

相关文章

  • 解析Spring中的循环依赖问题:初探三级缓存
    什么是循环依赖?这个情况很简单,即A对象依赖B对象,同时B对象也依赖A对象,让我们来简单看一下。//A依赖了BclassA{publicBb;}//B依赖了AclassB{publicAa;}这种循环依赖可能会引发问题吗?在没有考虑Spring框架的情况下,循环依赖并不会带来问题,因为对象之间相互依赖......
  • SpringCloud和SpringBoot的版本依赖该怎么选择
    前言SpringCloud是一个基于SpringBoot的微服务框架,用于构建和管理分布式系统的各个组件。它提供了一套完整的解决方案,包括服务注册与发现、配置管理、负载均衡、熔断器、消息总线、数据流等功能。SpringCloud2023为当前SpringCloud的最新版本迭代,基于Spring6和Springboot3以......
  • 控制反转IOC与依赖注入DI
    控制反转IOC与依赖注入DI需要掌握DI和IOC的含义是什么?掌握NetCore自带的依赖注入原理以及如何实现的流程以及熟悉对应的接口作用。学会在你的项目中集成AutoFacIOC控制反转--思想什么是IOC?IOC即控制反转,记住他是一种思想,目的是用来管理项目中对象的生命周期和依赖关......
  • 禁止edge自动将http转换为https的设置
    1.输入edge://flags/#edge-automatic-https,将AutomaticHTTPS设置为disabled。 2.输入edge://settings/searchFilters,关闭“使用我键入的字符向我显示此设备上的历史记录、收藏夹和其他数据的建议”此功能变能够关闭自动跳转改功能。 ......
  • vscode报错,nodemon 在此系统上禁止运行脚本
    1.vscode报错,nodemon:因为在此系统上禁止运行脚本注意:不仅仅适用于nodemon报错,报在此系统上禁止运行脚本的错都可以用以下方法解决2.报错原因分析:windows为了安全,默认的执行策略为Restricted,因此需要将执行策略设置为RemoteSigned即可3.解决方法  (1)get-exec......
  • ASP.NET MVC中使用Autofac依赖注入
      ASP.NETMVC中使用Autofac依赖注入官网文档:https://docs.autofac.org/en/latest/integration/mvc.html2024年02月26日在.net4.8framework建立的MVC项目中测试通过引入NUGET包:Autofac和Autofac.Mvc5Global中加入以下代码: //autofac注入ContainerBuilderbuil......
  • 【国产化】禁止使用不安全的密码算法:DES、RC2,RSA(1024位及以下),MD5,SHA1
    一、引言随着互联网的普及和技术的发展,网络安全问题日益严重。密码算法作为网络安全的基石,其安全性直接关系到用户数据的安全。一些不安全的密码算法不断被曝光,给用户带来了极大的安全隐患。二、不安全的密码算法1.DESDES(DataEncryptionStandard)是一种对称加密算法,自1977年......
  • 依赖注入(Dependency Injection, DI)是一种设计模式,例如,在React中,父组件可以通过props向
    依赖注入renderprops其实就是React世界中的“依赖注入”(DependencyInjection)。所谓依赖注入,指的是解决这样一个问题:逻辑A依赖于逻辑B,如果让A直接依赖于B,当然可行,但是A就没法做得通用了。依赖注入就是把B的逻辑以函数形式传递给A,A和B之间只需要对这个函数......
  • Net8 Autofac实现依赖注入(构造函数注入、属性注入)
    项目以net8建立为例子(net6也通用),使用Autofac实现构造函数注入、属性注入两种。引用以下packageAutofacAutofac.Extensions.DependencyInjectionMicrosoft.Extensions.DependencyModel在program下添加autofacbuilder.Host.UseServiceProviderFactory(newAutofacServicePr......
  • composer 安装依赖包出错,使用-W 参数升级包
    使用composer安装依赖失败composerrequirefriendsofhyperf/pest-plugin-hyperf--dev提示信息:Usetheoption--with-all-dependencies(-W)toallowupgrades,downgradesandremovalsforpackagescurrentlylockedtospecificversions.Youcanalsotryre-runni......