spring中AB类构造器存在循环依赖咋办

这篇具有很好参考价值的文章主要介绍了spring中AB类构造器存在循环依赖咋办。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

A 和 B 的构造器存在循环依赖

当 A 和 B 的构造器存在循环依赖时,SmartInstantiationAwareBeanPostProcessor 无法解决这种循环依赖问题。在这种情况下,Spring 会抛出一个异常,提示用户存在循环依赖。这是因为 Spring 采用的是构造器注入,而构造器注入无法像属性注入那样提前暴露引用来解决循环依赖。

具体过程如下:

  1. Spring 容器开始实例化 A,发现 A 有一个构造器 A(B b)。

  2. 容器尝试实例化 B 以满足 A 的依赖。然后发现 B 也有一个构造器 B(A a)。

  3. 容器尝试实例化 A 以满足 B 的依赖,此时发现 A 已经在实例化过程中了。这表明存在循环依赖。

  4. Spring 无法解决这种构造器循环依赖,会抛出一个异常,如 BeanCurrentlyInCreationException,提示用户存在循环依赖。

解决

要解决这种问题,可以采用以下方法:

  1. 使用属性注入(setter 注入)或使用 @Autowired 注解在字段上进行注入,这样 Spring 可以通过提前暴露引用的方式解决循环依赖问题。例如,将 A 和 B 的构造器依赖改为属性依赖:
@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private A a;

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}

  1. 使用懒加载(Lazy Loading)来解决循环依赖。在 Bean 的依赖声明上添加 @Lazy 注解,这样 Spring 容器在初始化 Bean 时将不会立即创建依赖的实例。当实际使用到依赖的对象时,容器才会创建并注入。例如:
@Component
public class A {
    private B b;

    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}

@Component
public class B {
    private A a;

    @Autowired
    public B(@Lazy A a) {
        this.a = a;
    }
}

  1. 如果可能,可以考虑调整类之间的依赖关系,将循环依赖拆分为线性依赖。这可以通过引入新的类或接口来实现,或者通过修改现有类的依赖关系实现。我们可以将 D 模块设置为调度器或者中介者,而不是直接依赖 A 和 B。我们可以将 A 和 B 作为 D 的依赖项进行注册,从而避免在 A 和 B 中直接依赖 D。以下是一个调整后的示例:
// A 模块
@Component
public class A {
    // A 的其他属性和方法

    // 注册 A 到 D 模块
    @Autowired
    public void registerToD(D d) {
        d.registerA(this);
    }
}

// B 模块
@Component
public class B {
    // B 的其他属性和方法

    // 注册 B 到 D 模块
    @Autowired
    public void registerToD(D d) {
        d.registerB(this);
    }
}

// D 模块,处理 A 和 B 之间的交互
@Component
public class D {
    private A a;
    private B b;

    public void registerA(A a) {
        this.a = a;
    }

    public void registerB(B b) {
        this.b = b;
}

// 在 D 中处理 A 和 B 之间的交互
public void processInteraction() {
    // 使用 a 和 b 的方法来实现交互逻辑
}
}

在这个调整后的示例中,我们将 A 和 B 注册到 D 模块,而不是让 A 和 B 直接依赖 D。这样,我们解决了 A 和 B 与 D 之间的循环依赖问题。同时,我们仍然可以在 D 模块中处理 A 和 B 之间的交互逻辑。

这种调整后的模块化设计方法可以有效地解决循环依赖问题,同时保持代码的可维护性和可读性。当然,在实际项目中,我们需要根据具体需求和场景选择合适的解决方案。


需要注意的是,以上提到的懒加载方法在某些情况下可能会引发其他问题,例如在多线程环境下可能会导致 Bean 实例化多次。因此,在使用懒加载时需要对应用的具体需求和场景进行评估,确保其能够正常运行。

总结

总之,对于构造器循环依赖的问题,我们需要调整代码结构,以便让 Spring 容器能够正确处理依赖关系。在实际项目中,应避免产生循环依赖的情况,以提高代码的可维护性和可读性。如果确实需要处理循环依赖,可以采用属性注入、懒加载或调整依赖关系等方法解决。文章来源地址https://www.toymoban.com/news/detail-401848.html

到了这里,关于spring中AB类构造器存在循环依赖咋办的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中构造器详解(类的五成员之三:构造器)

    先看文章目录,大致了解知识点结构,直接点击文章目录可以跳转到文章指定位置。 Java的基本单位是类,类中包含五个部分,这篇写的是 构造器 。 (1)变量 (2)方法 (3)构造器 (4)初始化块 (5)内部类 ①构造器是处于Java类中的一个方法,最大的作用创建对象时执行

    2024年02月08日
    浏览(42)
  • 7.5 构造器详解

    7.5 构造器详解 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点: 必须和类的名字相同 必须没有返回类型,也不能写void 一个类即使什么都不写都会存在一个构造方法。 构造器的作用 可以实例化一些初始值,比如一些游戏

    2024年02月14日
    浏览(37)
  • Java 构造器

    2024年02月12日
    浏览(112)
  • 单例模式与构造器模式

    单例模式(Singleton Pattern):创建型模式,提供了一种创建对象的最佳方式,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建 在应用程序运行期间,单例模式只会在全局作用域下创建一次实例对象,让所有需要调用的地方都共享这一单

    2024年02月15日
    浏览(36)
  • MyBatis-Plus:条件构造器Wrapper

    目录 1.Wrapper概述 1.1.Wrapper的继承关系 1.2.Wapper介绍  1.3.各个构造器使用区别 1.4.构造器常用方法 2.Wrapper常用构造器介绍 2.1.QueryWrapper 2.2.UpdateWrapper 2.3.LambdaQueryWrapper 2.4.AbstractWrapper 3. Lambda条件构造器 3.1.示例 4.鸣谢         我们在实际操作数据库的时候会涉及到很多的条件

    2024年02月11日
    浏览(63)
  • Java中使用es条件构造器BoolQueryBuilder

    由于es在java中查询没法像mybatis那样方便,而且es的构造器使用也比较繁琐,理解不是很方便,所以写一篇文章来记录es构造器BoolQueryBuilder查询时各种条件的构造的正确姿势。 1.构造准备 2.条件构造 must可用filter代替,查询效率会更高,因为must会对结果进行_score评估 3.构造完成

    2024年02月11日
    浏览(53)
  • JavaScript设计模式(一)——构造器模式、原型模式、类模式

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,正逐渐往全干发展 📃 个人状态: 研发工程师,现效力于中国工业软件事业 🚀 人生格言: 积跬步至千里,积小流成江海 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒

    2024年02月11日
    浏览(41)
  • MyBatis-Plus深入 —— 条件构造器与插件管理

            在前面的文章中,荔枝梳理了一个MyBatis-Plus的基本使用、配置和通用Service接口,我们发现在MyBatis-Plus的辅助增强下我们不再需要通过配置xml文件中的sql语句来实现基本的sql操作了,不愧是最佳搭档!在这篇文章中,荔枝会着重梳理有关MyBatis-Plus的两个知识点:条

    2024年02月09日
    浏览(49)
  • Java8函数式接口, 方法引用, 构造器引用, 数组引用

    只包含一个抽象方法的接口,称为函数式接口。 你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明 我们可以在一个接口上使用 @Functionallnterface 注解,这样做可以检查它是

    2024年02月05日
    浏览(56)
  • MybatisPlus-CRUD,不带条件构造器的常用方法

    BaseMapper中封装好了增删改查的方法 后面直接调用就好了 测试类 ----------------------------------------------------------------- ServiceImpl中封装了方法(特别注意批量添加只有serviceImpl中有) 测试类

    2024年02月14日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包