阅读 165

SpringBoot2.6.x默认禁用循环依赖后的问题解决

由于SpringBoot从底层逐渐引导开发者书写规范的代码,同时也是个忧伤的消息,循环依赖的应用场景实在是太广泛了,所以SpringBoot 2.6.x不推荐使用循环依赖,本文给大家说下SpringBoot2.6.x默认禁用循环依赖后的应对策略,感兴趣的朋友一起看看吧

目录
  • 一、序言

  • 二、问题复原

    • 1、代码说明

    • 2、错误示例

  • 三、问题解决

    • 1、粗暴解决

    • 2、优雅解决

  • 四、小结

    一、序言

    SpringBoot 2.6.x不推荐使用循环依赖,这是一个好消息,SpringBoot从底层逐渐引导开发者书写规范的代码,同时也是个忧伤的消息,循环依赖的应用场景实在是太广泛了。

    如果从低版本升级到2.6.x,那么很大概率遇到的第一个问题便是循环依赖问题。

    二、问题复原

    1、代码说明

    下面风格的代码比较普遍:两个类都有调用对方方法的需求,因此很容易写成循环引用。

    1
    2
    3
    4
    5
    6
    @Service
    public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService {
         
        @Autowired
        private ITbStaffService staffService;
    }
    1
    2
    3
    4
    5
    @Service
    public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService {
        @Autowired
        private ITbDeptService deptService;
    }

    2、错误示例

    Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

    Despite circular references being allowed, the dependency cycle between beans could not be broken. Update your application to remove the dependency cycle.

    三、问题解决

    1、粗暴解决


    最简单的方式是在全局配置文件中允许循环引用存在,此属性默认值为false,显示声明为true,可回避项目启动时控制台循环引用异常。

    1
    2
    3
    spring:
      main:
        allow-circular-references: true

    2、优雅解决

    Spring官方默认禁止使用循环依赖,尽管留有可选配置,允许开发者继续使用循环依赖。

    Spring官方的初心是不希望开发者编写循环依赖的代码,也就是说未来的某个版本可能强制不得使用循环依赖,因此逐渐在新项目中消除循环依赖是不得不面对的问题。

    使用方法的返回值获取实例对象,替换通过成员变量注入实例对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Service
    public class TbDeptServiceImpl extends ServiceImpl<TbDeptMapper, TbDept> implements ITbDeptService {
        /**
         * 使用方法返回实例对象,替换成员变量注入
         * @return ITbStaffService
         */
        public ITbStaffService getStaffService(){
            return SpringUtils.getBean(ITbStaffService.class);
        }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Service
    public class TbStaffServiceImpl extends ServiceImpl<TbStaffMapper, TbStaff> implements ITbStaffService {
        /**
         * 使用方法返回实例对象,替换成员变量注入
         * @return ITbStaffService
         */
        public ITbDeptService getDeptService(){
            return SpringUtils.getBean(ITbDeptService.class);
        }
    }

    其中需要使用如下依赖,此依赖是笔者抽离出来的公共依赖,可跨项目使用。

    1
    2
    3
    4
    5
    <dependency>
        <groupId>xin.altitude.cms.common</groupId>
        <artifactId>ucode-cms-common</artifactId>
        <version>1.3.4</version>
    </dependency>

    如果找不到此依赖,很大可能是阿里云Maven仓库尚未同步,在项目中强制使用Maven中央仓库即可。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <repositories>
        <repository>
            <id>public</id>
            <name>maven nexus</name>
            <url>https://repo1.maven.org/maven2/</url>
            <snapshots>
                <updatePolicy>always</updatePolicy>
            </snapshots>
        </repository>
    </repositories>

    四、小结

    Spring生态作为广泛使用的框架,俨然成为Java企业级应用主流标准,其微小的变化对整合生态带来不可估量的影响。从跟随者转化为引导者,果断禁止循环依赖问题,体现的是作为引导者的担当。

    循环引用使用习惯了,初步看起来代码没毛病,仔细想想是不合理的设计。循环依赖的直接表现是你中有我,我中有你,从对象的设计上令人费解。

    最为开发者时刻关注底层框架的变动,将会在应用层收益。这里所说的底层框架是指JDK、Spring生态、Apache、知名大厂开源并广泛被应用的框架,比如guava等。

    到此这篇关于SpringBoot2.6.x默认禁用循环依赖后的应对策略的文章就介绍到这了

    原文链接:https://blog.51cto.com/u_15495434/5038961


    文章分类
    代码人生
    版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
    相关推荐