2021年2月24日星期三

Spring循环依赖问题的解决

循环依赖问题

一个bean的创建分为如下步骤:

当创建一个简单对象的时候,过程如下:

  • 先从单例池中获取bean,发现无 a
  • 创建 a 的实例
  • 为 a 赋值
  • 把 a 放到单例池中

当创建一个对象并且其中有另外一个对象是就变成了这样:

但是当在B对象中由引用了A对象,就会变成这样:

因为A和B两者相互引用,但是单例池中始终无法创建任一对象,所以会出现死循环。

因此,我们需要添加一个半成品池,先把A初始化出来,放到一个半成品池中。

过程如下:

  • 先从单例池中找A对象,没有则开始创建A对象
  • 实例化A对象,并放入半成品池中
  • 为A对象赋值
  • 赋值时发现引用了B对象 --> 实例化B对象,并放入半成品池中
  • 为B对象赋值
  • 赋值时发现引用了A对象,从单例池中和半成品池中找A对象,并将其赋值
  • 实例化B对象,并放入单例池中
  • 实例化A对象,从半成品池中移除A对象,并放入单例池中

这样就解决了死循环创建但是当使用了动态代理后,情况又会有所变化.

先来看一下AOP的执行过程,如图:

在bean的创建过程中,创建动态代理的时机是在初始化之后的,如图:

这个时候半成品池里放的是没有代理过的A对象,当B去半成品池中获取A对象,获取的是动态代理前的A对象,而我们应该获取的是动态代理后的A对象,这就会出现问题.

为了解决AOP的问题,spring又加入了一个工厂池

执行过程如下:

  • 当创建A对象的时候会在工厂池中创建factory(a)
  • ....
  • 当给B赋值时,发现引用了A,就会去工厂池中执行getEarlyReference 提前处理方法,生成一个动态代理后的A对象,并放入半成品池中,再赋值给B
  • ...

注意:

​ 当实例化对象A的时候,A对象会产生与之对应的factory(a)方法,只有当某个对象引用A对象时,factory(a)方法才会被执行,从而去通过提前引用的方式创建动态代理对象放入半成品池中

如果说A对象没有被提前引用,factory(a)方法不会执行









原文转载:http://www.shaoqun.com/a/581587.html

跨境电商:https://www.ikjzd.com/

ensogo:https://www.ikjzd.com/w/1485

雨果:https://www.ikjzd.com/w/1307


循环依赖问题一个bean的创建分为如下步骤:当创建一个简单对象的时候,过程如下:先从单例池中获取bean,发现无a创建a的实例为a赋值把a放到单例池中当创建一个对象并且其中有另外一个对象是就变成了这样:但是当在B对象中由引用了A对象,就会变成这样:因为A和B两者相互引用,但是单例池中始终无法创建任一对象,所以会出现死循环。因此,我们需要添加一个半成品池,先把A初始化出来,放到一个半成品池中。过程如
盘古集团:https://www.ikjzd.com/w/1448
巴克莱:https://www.ikjzd.com/w/2775
克雷格:https://www.ikjzd.com/w/194
亚马逊LISTING流程化运营体系:亚马逊假日账号工作管理安排:https://www.ikjzd.com/home/114899
打造爆款最后一公里之细节实操:https://www.kjyunke.com/courses/54
什么是亚马逊跟卖,亚马逊跟卖的优劣势?怎样进行合理的亚马逊跟卖?:https://www.ikjzd.com/home/99608

没有评论:

发表评论