Spring如何解决循环依赖?

Spring如何解决循环依赖?

spring是怎么解决循环依赖的,一级、二级、三级缓存扮演什么角色?

本次分享,包括

1.一个简单的单例Bean的实例化过程

2.存在依赖的单例Bean的实例化过程

3.存在循环依赖的单例Bean的实例化过程

一个简单的单例Bean的实例化过程

定义一个SimpleBean

package com.mytest.spring;

import org.springframework.stereotype.Component;

public class SimpleBean {

    public SimpleBean() {
        System.out.println("SimpleBean 创建了");
    }

    public void say() {
        System.out.println("SimpleBean say");
    }
}

定义一个测试类MySpringTest

package com.mytest.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(SimpleBean.class);
        annotationConfigApplicationContext.refresh();
    }
}

annotationConfigApplicationContext.refresh()会调finishBeanFactoryInitialization(beanFactory),该方法会完成单例bean的实例化。

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

SimpleBean实例化过程图:
spring源码分析-无依赖

因没有属性依赖流程比较简单,

创建的单例bean会存在一级缓存,再次获取bean时直接从一级缓存中获取。接着我们来看存在依赖的Bean实例化过程。

存在依赖的单例Bean的实例化过程

定义一个带@Autowired的类HasAutowiredBean

package com.mytest.spring;

import org.springframework.beans.factory.annotation.Autowired;

public class HasAutowiredBean {

    @Autowired
    private SimpleBean simpleBean;

    public HasAutowiredBean() {
        System.out.println("HasAutowiredBean 创建了");
    }

    public void say() {
        System.out.println("HasAutowiredBean say");
    }
}

测试类MySpringTest中注册HasAutowiredBean.class

package com.mytest.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(SimpleBean.class);
        annotationConfigApplicationContext.register(HasAutowiredBean.class);
        annotationConfigApplicationContext.refresh();
    }
}

实例化过程如图:

过程也很简单,先实例化Bean:hasAutowiredBean,再根据@Autowired实例化Bean:simpleBean。

实例化完成都将放入一级缓存中。

存在循环依赖的单例Bean的实例化过程

定义一个类CircleAutowiredBeanA,其中依赖了CircleAutowiredBeanB

package com.mytest.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CircleAutowiredBeanA {

    @Autowired
    private CircleAutowiredBeanB circleAutowiredBeanB;

    public CircleAutowiredBeanA() {
        System.out.println("CircleAutowiredBeanA 创建了");
    }

    public void say() {
        System.out.println("CircleAutowiredBeanA say");
    }
}

再定义一个类CircleAutowiredBeanB,其中依赖了CircleAutowiredBeanA

package com.mytest.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CircleAutowiredBeanB {

    @Autowired
    private CircleAutowiredBeanA circleAutowiredBeanA;

    public CircleAutowiredBeanB() {
        System.out.println("CircleAutowiredBeanB 创建了");
    }

    public void say() {
        System.out.println("CircleAutowiredBeanB say");
    }
}

类的关系如图:
image-20220425140447538

修改测试类MySpringTest

package com.mytest.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(CircleAutowiredBeanA.class);
        annotationConfigApplicationContext.register(CircleAutowiredBeanB.class);
        annotationConfigApplicationContext.refresh();
    }
}

执行完,输出:

CircleAutowiredBeanA 创建了
CircleAutowiredBeanB 创建了

实例化过程图:

为解决循环依赖,流程有点复杂,大概步骤:

1)首先加载Bean:circleAutowiredBeanA,实例化一个对象,记录circleAutowiredBeanA的三级缓存

2)给circleAutowiredBeanA的属性circleAutowiredBeanB赋值,加载Bean:circleAutowiredBeanB,实例化一个对象

3)给circleAutowiredBeanB的属性circleAutowiredBeanA赋值,从三级缓存中获取到circleAutowiredBeanA对象(此时的circleAutowiredBeanA,可能会由先前加入到三级缓存中的函数接口创建一个代理对象),加入到二级缓存;然后给属性circleAutowiredBeanA赋值。

4)circleAutowiredBeanB对象赋值完成,初始化,然后加入到一级缓存,并返回给circleAutowiredBeanA。

5)加载完circleAutowiredBeanB,回到circleAutowiredBeanA。获取二级缓存的circleAutowiredBeanA对象,添加到一级缓存。

到此,Spring循环依赖分享完毕,有问题欢迎指正。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值