Spring循环依赖的解决方案详解

 更新时间:2022年07月09日 09:46:07   作者:IT利刃出鞘  
这篇文章将用实例为大家详细介绍了介绍如何解决Spring的循环依赖问题,文中的示例代码讲解详细,对我们学习Spring有一定的帮助,需要的可以参考一下

简介

说明

本文用实例介绍如何解决Spring的循环依赖问题。

相关网址

Spring循环依赖之问题复现详解

公共代码

package com.example.controller;
 
import com.example.tmp.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @Autowired
    private A a;
 
    @GetMapping("/test1")
    public String test1() {
        return a.getTest();
    }
}

方案1. Feild注入单例(@AutoWired)

代码

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    @Autowired
    private B b;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
}

测试

启动不报错。

postman访问:http://localhost:8080/test1

后端结果:不报错

postman结果: 20Tony

方案2. 构造器注入+@Lazy

延迟加载:在注入依赖时,先注入代理对象,当首次使用时再创建对象完成注入。

代码

package com.example.tmp;
 
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    private B b;
 
    public A(@Lazy B b) {
        this.b = b;
    }
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    private A a;
 
    public B(@Lazy A a) {
        this.a = a;
    }
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
}

测试

启动不报错。

postman访问:http://localhost:8080/test1

后端结果:不报错

postman结果: 20Tony

方案3. Setter/Field注入单例

代码

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    private B b;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
 
    public B getB() {
        return b;
    }
 
    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public A getA() {
        return a;
    }
 
    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}

测试 

启动不报错。

postman访问:http://localhost:8080/test1

后端结果:不报错

postman结果: 20Tony

方案4. @PostConstruct

代码

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
 
@Component
public class A {
    @Autowired
    private B b;
 
    @PostConstruct
    public void init() {
        b.setA(this);
    }
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public A getA() {
        return a;
    }
 
    public void setA(A a) {
        this.a = a;
    }
}

测试 

启动不报错。

postman访问:http://localhost:8080/test1

后端结果:不报错

postman结果: 20Tony

方案5. 实现ApplicationContextAware与InitializingBean

代码 

package com.example.tmp;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 
@Component
public class A implements ApplicationContextAware, InitializingBean {
    private B b;
 
    private ApplicationContext context;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
 
    @Override
    public void afterPropertiesSet() throws Exception {
        this.b = context.getBean(B.class);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
}

测试 

启动不报错。

postman访问:http://localhost:8080/test1

后端结果:不报错

postman结果: 20Tony

以上就是Spring循环依赖的解决方案详解的详细内容,更多关于Spring循环依赖的资料请关注脚本之家其它相关文章!

相关文章

  • JAVA内存溢出解决方案图解

    JAVA内存溢出解决方案图解

    这篇文章主要介绍了JAVA内存溢出解决方案图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Spring Boot 配置 Quartz 定时任务的方法

    Spring Boot 配置 Quartz 定时任务的方法

    这篇文章主要介绍了Spring Boot 配置 Quartz 定时任务的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Java利用自定义注解、反射实现简单BaseDao实例

    Java利用自定义注解、反射实现简单BaseDao实例

    下面小编就为大家带来一篇Java利用自定义注解、反射实现简单BaseDao实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Java Controller实现参数验证与统一异常处理流程详细讲解

    Java Controller实现参数验证与统一异常处理流程详细讲解

    Controller是Spring接受并处理网页请求的组件,是整个应用的入口,因此学会Controller的常用注解对理解一个应用是重中之重。SpringBoot的Controller中经常会用到注解@Controller、@RestController、@RequestMapping、@RequestBody等
    2023-01-01
  • Java实现递归删除菜单和目录及目录下所有文件

    Java实现递归删除菜单和目录及目录下所有文件

    这篇文章主要为大家详细介绍了Java如何实现递归删除菜单和删除目录及目录下所有文件,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下
    2025-03-03
  • JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详解

    JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详

    这篇文章主要介绍了JAVA开发常用类库UUID、Optional、ThreadLocal、TimerTask、Base64使用方法与实例详解,需要的朋友可以参考下
    2020-02-02
  • Java实现解压zip压缩包的两种方法(支持多层级)

    Java实现解压zip压缩包的两种方法(支持多层级)

    压缩文件在生活中经常能用到,在Java中提供了压缩和解压缩文件的功能,本文主要介绍了Java实现解压zip压缩包的两种方法(支持多层级),感兴趣的可以了解一下
    2024-03-03
  • SpringBoot中的ApplicationListener事件监听器使用详解

    SpringBoot中的ApplicationListener事件监听器使用详解

    这篇文章主要介绍了SpringBoot中的ApplicationListener事件监听器使用详解,ApplicationListener是应用程序的事件监听器,继承自java.util.EventListener标准接口,采用观察者设计模式,需要的朋友可以参考下
    2023-11-11
  • hibernate中的对象关系映射

    hibernate中的对象关系映射

    hibernate中的ORM映射文件通常以.hbm.xml作为后缀。使用这个映射文件不仅易读,而且可以手工修改,也可以通过一些工具来生成映射文档,下文给大家详细的介绍hibernate中的对象关系映射,需要的朋友参考下吧
    2017-09-09
  • SpringBoot集成ActiveMQ的实战全过程

    SpringBoot集成ActiveMQ的实战全过程

    消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题,实现高性能、高可用、可伸缩和最终一致性架构,是大型分布式系统不可缺少的中间件,这篇文章主要给大家介绍了关于SpringBoot集成ActiveMQ的相关资料,需要的朋友可以参考下
    2021-11-11

最新评论