Spring中又是由哪些"角色"构成
ApplicationContext作为Spring的核心,它的实现类如下:
一个Spring的启动流程:
整体流程图:
通过BeanDefinitionReader,来加载bean的配置信息,然后生成一个BeanDefinition(bean的定义信息,用来存储 bean 的所有属性方法定义)
BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,其实就是在bean的实例化之前,可以获取bean的定义信息,以及修改相关信息。
BeanFactory,从名字上也很好理解,生产 bean 的工厂,它负责生产和管理各个 bean 实例。同时也是Spring容器暴露在外获取bean的入口。生产过程其实是利用反射机制实现的
SpringBean的生命周期可以缩短理解为:
Spring容器启动流程
Spring 里面的循环依赖问题:
三层缓存加上 提前暴露对象的方式(半成品)解决循环依赖问题。
一个对象的创建 -> 实例化 -> 初始化(设置属性值) 那构造器的那种方式在流程中怎么体现出这个环呢?给大家画了一个图如下:
按照上面的创建流程那整个循环依赖就产生了 三层缓存依赖,其实就是先把实例化的对象,放置在缓存中,等后续在根据A对象的引用完成赋值操作。 处理完的流程就是如下所示:
在改进的图中其实已经可以发现,环 已经被打开了。整个可以如下几步:
**在实例化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个方法: