spring解决循环依赖的方法(简易版理解)

一、什么是循环依赖

spring中我们的类都交由spring来管理,当我们的类中存在这样一种现象时,会出现循环依赖问题。

假如有两个对象A和B,我们在A中调用了B,又在B中调用了A。如果不使用spring,我们自己编写类,只需要在两个对象中都new出对方即可。但此时我们把这两个对象都交由spring管理,即在配置中写两个bean。当spring在创建bean的时候,spring却不能向我们一样new出对象,所以就出现了循环依赖问题。

二、出现循环依赖的主要原因

1.死循环创建

2.AOP动态代理

三、spring是如何解决该问题的

首先,我们要清楚spring创建bean的过程:

spring创建bean的基本过程是:

1.获取bean  ->  2.此时spring会去单例池中寻找,如果有直接返回  ->  3.如果单例池中没有,spring就会实例化,填充属性,初始化。

spring解决循环依赖的方法概述

在这个过程中,spring为了避免循环依赖出现死循环创建和AOP动态代理问题,就给出了一种解决方案,spring会提供三个缓存,一级缓存就是我们的单例池,二级缓存,我们暂时称为半成品池,三级缓存,我们称为工厂池,通过这三个缓存池来解决该问题,具体怎么解决看下面的例子。

(singletonObjects 一级缓存,earlySingletonObjects 二级缓存,singletonFactories 三级缓存)

spring解决循环依赖的例子

例子背景:假设现在A对象被AOP动态代理,且A和B两者相互依赖

例子spring解决方案过程如下:

在创建A时,先获取A的bean,然后取单例池中寻找,没有,则进行实例化,在实例化中因为有AOP动态代理,所以或现将其实例并放进工厂池,然后填充属性,此时因为我们在A中调用了B,所以,spring会获取B的bean,在单例池中找B,如果单例池没有B,则实例化并填充B的属性,此时就又会调用A,因为A和B相互依赖,所以spring会再去获取A,此时我们回去三个缓存池中寻找,最后会在三级缓存也就是工厂池中获取到A,此时将A放进半成品池中,此时B就填充完了属性,就会初始化,并存入单例池。因为B已经进入了单例池,spring也就完成了A的属性填充,A的创建就可以继续向下进行,进行初始化,然后A也存入单例池。至此,A的bean已经创建完成。

B的创建也是同理,注意如果三个缓存中本来就有,则在获取bean的时候就会直接拿到,不在走上述流程。

如果有上述有什么问题,欢迎评论指证,这只是我在学习后的总结,大致方向应该不会错,一些细节可能不太准确。

你可能感兴趣的:(知识记录,spring,java,后端,缓存)