spring解决循环依赖的方案

简介: spring解决循环依赖的方案

问题描述

当ServiceA和ServiceB相互依赖的时候,就会出现循环依赖的问题,循环依赖的代码可能如下:

@Component
public class A {
    // A中注入了B
    @Autowired
    private B b;
}
@Component
public class B {
    // B中也注入了A
    @Autowired
    private A a;
}

在启动服务的时候会报错。

问题分析

解决循环依赖的思路有两种,一种是在相互依赖的bean中新增中间状态,在一方依赖另一方的时候先给其一个中间状态的引用,待依赖双方创建完成后,再进行初始化,这个是spring解决循环依赖的思路。

另一种是在一个依赖的bean创建成功之后,再创建另一个bean,或者再手动触发另一个bean的依赖注入。这个是手动解决依赖注入的思路。

解决方案

方案一:

使用属性注入或setter注入方式。这种方式spring框架解决了注入依赖的问题。

@Component
public class Service1 {
    @Autowired
    private Service2 service2;
}
@Component
public class Service1 {
    private Service2 service2;
    @Autowired
    public Service1(Service2 service2) {
        this.service2 = service2;
    }
}

在springboot中使用以上方法解决注入依赖,还是会报依赖注入的错误,需要在配置文件application.properties中添加配置项:spring.main.allow-circular-references=true

方案二:

使用@Lazy。使用Bean的懒加载方式,在bean需要的时候才初始化它,这样规避了启动context的时候对有依赖关系的bean进行初始化从而报错的问题。

@Component
public class Service1 {
    private Service2 service2;
    @Autowired
    public void setService2(@Lazy Service2 service2) {
        this.service2 = service2;
    }
}

方案三:

使用@PostConstruct注解,在一个bean初始化后再初始化另一个。

@Component
public class CircularDependencyA {
    @Autowired
    private CircularDependencyB circB;
    @PostConstruct
    public void init() {
        circB.setCircA(this);
    }
    public CircularDependencyB getCircB() {
        return circB;
    }
}

方案四:

实现InitializingBean。该接口可以实现在bean初始化前后再进行操作的功能,通过实现ApplicationContextAware接口。

@Component
public class CircularDependencyA implements ApplicationContextAware, InitializingBean {
    private CircularDependencyB circB;
    private ApplicationContext context;
    public CircularDependencyB getCircB() {
        return circB;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        circB = context.getBean(CircularDependencyB.class);
    }
    @Override
    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
        context = ctx;
    }
} 

问题总结

以上的解决循环依赖的方案都是存在循序依赖后才介入解决,其实最好的思路应该是不要再代码中存在循序依赖的逻辑,这样的逻辑本身可能就不合理


目录
相关文章
|
6天前
|
人工智能 Java Spring
Spring Boot循环依赖的症状和解决方案
Spring Boot循环依赖的症状和解决方案
|
6天前
|
安全 Java 数据安全/隐私保护
|
6天前
|
缓存 Java 开发工具
【spring】如何解决循环依赖
【spring】如何解决循环依赖
15 0
|
6天前
|
存储 缓存 Java
【Spring系列笔记】依赖注入,循环依赖以及三级缓存
依赖注入: 是指通过外部配置,将依赖关系注入到对象中。依赖注入有四种主要方式:构造器注入、setter方法注入、接口注入以及注解注入。其中注解注入在开发中最为常见,因为其使用便捷以及可维护性强;构造器注入为官方推荐,可注入不可变对象以及解决循环依赖问题。本文基于依赖注入方式引出循环依赖以及三层缓存的底层原理,以及代码的实现方式。
24 0
|
6天前
|
存储 缓存 Java
【spring】06 循环依赖的分析与解决
【spring】06 循环依赖的分析与解决
10 1
|
6天前
|
存储 缓存 Java
Spring解决循环依赖
Spring解决循环依赖
|
6天前
|
缓存 算法 Java
开发必懂的Spring循环依赖图解 Spring 循环依赖
开发必懂的Spring循环依赖图解 Spring 循环依赖
22 1
|
6天前
|
缓存 算法 Java
Spring解决循环依赖
Spring解决循环依赖
21 1
|
6天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
63 0
|
6天前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
143 0