• Spring(SpringBoot)--循环依赖--解决方案--实例


    原文网址:Spring(SpringBoot)--循环依赖--解决方案--实例_IT利刃出鞘的博客-CSDN博客

    简介

    说明

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

    相关网址

    Spring(SpringBoot)--循环依赖--问题复现_IT利刃出鞘的博客-CSDN博客_springboot 配置循环依赖

    公共代码

    1. package com.example.controller;
    2. import com.example.tmp.A;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.web.bind.annotation.GetMapping;
    5. import org.springframework.web.bind.annotation.RestController;
    6. @RestController
    7. public class HelloController {
    8. @Autowired
    9. private A a;
    10. @GetMapping("/test1")
    11. public String test1() {
    12. return a.getTest();
    13. }
    14. }

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

    代码

    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class A {
    6. @Autowired
    7. private B b;
    8. private String name = "Tony";
    9. public String getName() {
    10. return name;
    11. }
    12. public void setName(String name) {
    13. this.name = name;
    14. }
    15. public String getTest() {
    16. return b.getAge().toString() + name;
    17. }
    18. }
    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class B {
    6. @Autowired
    7. private A a;
    8. private Integer age = 20;
    9. public Integer getAge() {
    10. return age;
    11. }
    12. public void setAge(Integer age) {
    13. this.age = age;
    14. }
    15. }

    测试

    启动不报错。

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

    后端结果:不报错

    postman结果: 20Tony

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

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

    代码

    1. package com.example.tmp;
    2. import org.springframework.context.annotation.Lazy;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class A {
    6. private B b;
    7. public A(@Lazy B b) {
    8. this.b = b;
    9. }
    10. private String name = "Tony";
    11. public String getName() {
    12. return name;
    13. }
    14. public void setName(String name) {
    15. this.name = name;
    16. }
    17. public String getTest() {
    18. return b.getAge().toString() + name;
    19. }
    20. }
    1. package com.example.tmp;
    2. import org.springframework.context.annotation.Lazy;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class B {
    6. private A a;
    7. public B(@Lazy A a) {
    8. this.a = a;
    9. }
    10. private Integer age = 20;
    11. public Integer getAge() {
    12. return age;
    13. }
    14. public void setAge(Integer age) {
    15. this.age = age;
    16. }
    17. }

    测试

    启动不报错。

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

    后端结果:不报错

    postman结果: 20Tony

    方案3. Setter/Field注入单例

    代码

    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class A {
    6. private B b;
    7. private String name = "Tony";
    8. public String getName() {
    9. return name;
    10. }
    11. public void setName(String name) {
    12. this.name = name;
    13. }
    14. public String getTest() {
    15. return b.getAge().toString() + name;
    16. }
    17. public B getB() {
    18. return b;
    19. }
    20. @Autowired
    21. public void setB(B b) {
    22. this.b = b;
    23. }
    24. }
    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class B {
    6. private A a;
    7. private Integer age = 20;
    8. public Integer getAge() {
    9. return age;
    10. }
    11. public void setAge(Integer age) {
    12. this.age = age;
    13. }
    14. public A getA() {
    15. return a;
    16. }
    17. @Autowired
    18. public void setA(A a) {
    19. this.a = a;
    20. }
    21. }

    测试 

    启动不报错。

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

    后端结果:不报错

    postman结果: 20Tony

    方案4. @PostConstruct

    代码

    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. import javax.annotation.PostConstruct;
    5. @Component
    6. public class A {
    7. @Autowired
    8. private B b;
    9. @PostConstruct
    10. public void init() {
    11. b.setA(this);
    12. }
    13. private String name = "Tony";
    14. public String getName() {
    15. return name;
    16. }
    17. public void setName(String name) {
    18. this.name = name;
    19. }
    20. public String getTest() {
    21. return b.getAge().toString() + name;
    22. }
    23. }
    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class B {
    6. @Autowired
    7. private A a;
    8. private Integer age = 20;
    9. public Integer getAge() {
    10. return age;
    11. }
    12. public void setAge(Integer age) {
    13. this.age = age;
    14. }
    15. public A getA() {
    16. return a;
    17. }
    18. public void setA(A a) {
    19. this.a = a;
    20. }
    21. }

    测试 

    启动不报错。

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

    后端结果:不报错

    postman结果: 20Tony

    方案5. 实现ApplicationContextAware与InitializingBean

    代码 

    1. package com.example.tmp;
    2. import org.springframework.beans.BeansException;
    3. import org.springframework.beans.factory.InitializingBean;
    4. import org.springframework.context.ApplicationContext;
    5. import org.springframework.context.ApplicationContextAware;
    6. import org.springframework.stereotype.Component;
    7. @Component
    8. public class A implements ApplicationContextAware, InitializingBean {
    9. private B b;
    10. private ApplicationContext context;
    11. private String name = "Tony";
    12. public String getName() {
    13. return name;
    14. }
    15. public void setName(String name) {
    16. this.name = name;
    17. }
    18. public String getTest() {
    19. return b.getAge().toString() + name;
    20. }
    21. @Override
    22. public void afterPropertiesSet() throws Exception {
    23. this.b = context.getBean(B.class);
    24. }
    25. @Override
    26. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    27. this.context = applicationContext;
    28. }
    29. }
    1. package com.example.tmp;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Component;
    4. @Component
    5. public class B {
    6. @Autowired
    7. private A a;
    8. private Integer age = 20;
    9. public Integer getAge() {
    10. return age;
    11. }
    12. public void setAge(Integer age) {
    13. this.age = age;
    14. }
    15. }

    测试 

    启动不报错。

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

    后端结果:不报错

    postman结果: 20Tony

  • 相关阅读:
    C++函数模板
    CUDA By Example(四)——线程协作
    【GlobalMapper精品教程】030:栅格重采样案例教程(航测DSM)
    【算法】堆排序 详解
    Web安全—Web漏扫工具NetSparker安装与使用
    USB-数据传输
    小谈设计模式(9)—工厂方法模式
    cdo入门
    conda环境安装opencv带cuda版本
    机器学习周记(第三十八周:语义分割)2024.5.6~2024.5.12
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/125358333