栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring如何解决循环依赖?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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实例化过程图:

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

创建的单例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");
    }
}

类的关系如图:

修改测试类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循环依赖分享完毕,有问题欢迎指正。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/839358.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号