Spring

119 阅读3分钟

Spring中又是由哪些"角色"构成

image.png

ApplicationContext作为Spring的核心,它的实现类如下: image.png 一个Spring的启动流程:

ioc.png

image.png

整体流程图:

0b0979eb9290130d8c41b0447c8a831e.jpg

通过BeanDefinitionReader,来加载bean的配置信息,然后生成一个BeanDefinition(bean的定义信息,用来存储 bean 的所有属性方法定义)

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,其实就是在bean的实例化之前,可以获取bean的定义信息,以及修改相关信息。

BeanFactory,从名字上也很好理解,生产 bean 的工厂,它负责生产和管理各个 bean 实例。同时也是Spring容器暴露在外获取bean的入口。生产过程其实是利用反射机制实现的

b21c970348b3de6936f12d1d30294b05.jpg

SpringBean的生命周期可以缩短理解为:

wxt.jpg

iocc.jpg


Spring容器启动流程

Spring 里面的循环依赖问题:

o1.jpg

三层缓存加上 提前暴露对象的方式(半成品)解决循环依赖问题。

o3.jpg

一个对象的创建 -> 实例化 -> 初始化(设置属性值) 那构造器的那种方式在流程中怎么体现出这个呢?给大家画了一个图如下:

7c6e5ac6d04f2a1a0f318fe9c44ed5bb.jpg

按照上面的创建流程那整个循环依赖就产生了 三层缓存依赖,其实就是先把实例化的对象,放置在缓存中,等后续在根据A对象的引用完成赋值操作。 处理完的流程就是如下所示:

11f23379d5f07c0897e3387b42951403.jpg 在改进的图中其实已经可以发现, 已经被打开了。整个可以如下几步:

**在实例化A对象之后就向容器中添加一个缓存,存放一个实例化但未初始化完成的对象(半成品对象)。

在第一次创建A对象中容器已经有一个A对象,但是没有B对象,所以在开始创建B对象时,在完成B对象的实例化之后,开始初始化属性赋值时,此时容器中已经有A对象,所以可以直接通过A的属性赋值,同样的B对象完成初始化之后也就可以再接着完成初始化A对象了,那整个A对象和B对象的创建过程就完成了。**

当开始创建A对象时,实例化后,添加一步三级缓存,针对属性赋值,因为此时还没有B对象的实例,所以在获取到A对象的B属性的值的ref引用对象B,触发创建B对象的创建,因此在B对象实例化后,在属性赋值时,获取到A属性的ref引用对象,而因为之前A对象已经完成实例化,并且添加到了三级缓存中,所以在B属性创建设置A属性时,因为此时A属性正在被创建,所以可以从第三级缓存中获取到值,同时把获取到的值添加到二级缓存中,同时删除第三级缓存的A对象。

在创建B对象中已经能获取到A属性值(半成品),所以B对象可以完成赋值状态,变成一个完整的B对象的实例。所以当新的单例对象生成会再调用addSingleton方法添加到一级缓存中,同时删除 二级 三级缓存的值,所以回过头来接着 A对象获取B属性值的时候已经能在一级缓存中获取到。所以也就可以完成属性赋值,自此循环依赖完全打开。

  • 一级:完整的成品的对象
  • 二级:非完整的半成品对象
  • 三级:lambada表达式

6个方法:

o1.jpg