创建了一个多播器,为添加Listener提供支持 。
主要逻辑:
- 容器中是否存在applicationEventMulticaster,如果存在直接注册
- 如果不存在,创建一个SimpleApplicationEventMulticaster,注册到容器中 。
子类扩展
3.3.10 registerListeners()
观察者模式的实现

文章插图
3.3.11 finishBeanFactoryInitialization
这一部分的内容太多了,所以采用代码和图解的方式来讲解 。

文章插图
下图是创建Bean的主要流程

文章插图
按照图中的序号一个一个说:
- BeanDefinition是否需要合并 。BeanDefinition根据不同类型的配置文件信息,会将Bean封装到不同的Bean信息定义类中 。比如我们常用的配置文件版的GenericBeanDefinition;注解扫描版的ScannedGenericBeanDefinition等等 。
- 存在父定义信息,使用父定义信息创建一个RootBeanDefinition,然后将自定义信息作为参数传入 。
- 不存在父定义信息,并且当前BeanDefinition是RootBeanDefintion类型的,直接返回一份RootBeanDefintion的克隆
- 不存在父定义信息,并且当前BeanDefintion不是RootBeanDefintiton类型的,直接通过该BeanDefintion构建一个RootBeanDefintion返回

文章插图
- isFactoryBean 。判断是否为FactoryBean

文章插图
当我们通过GetBean直接该Bean的时候,获取到的是该工厂指定返回的Bean类型 。如果想要获取该Bean本身,需要通过一个前缀获得&

文章插图
再来看一个点,这个就是从容器中获取Bean的主要方法,也是解决循环依赖的逻辑

文章插图
来聊一下它是怎么解决循环引用的?
它引入了一个三级缓存的概念

文章插图
在发生循环引用的时候,它首先通过ObejctFactory工厂将Bean创建出来,此时的对象并没有进行属性赋值,仅仅在堆中开辟了空间 。然后将此时的Bean添加到earlySingletonObjects容器里,也就是说这个容器中保存的Bean都是半成品 。而在之后的属性赋值中,由于对象为单例的,所以其引用地址不会发生变化,即对象最终是完整的 。
1.getBean 。通过这个方法直接创建了所有的对象,这也是Spring最核心的方法了,先来看一下它整体的一个流程

文章插图
它的主要逻辑是:
- 先拿到当前要实例化的Bean的真实名字,主要是为了处理FactoryBean,拿到以后,从当前容器中看是否已经创建过该Bean,如果存在直接返回 。
- 如果不存在,获取其父工厂,如果父工厂不为空,而且当前容器中不存在当前Bean的信息,则尝试从父工厂中获取Bean定义信息,进行Bean实例化
- 如果父工厂为空,将当前Bean信息存放到alreadyCreated缓存中 。
- 获取当前Bean的合并信息(getMergedLocalBeanDefinition),查看当前Bean是否存在依赖,如果存在则判断当前Bean和依赖 Bean 是否为循环依赖,如果不是循环依赖则先创建依赖Bean
- 判断当前Bean的作用域 。
- 如果当前Bean是单例对象,直接创建Bean实例
- 如果当前Bean是多例对象,将当前Bean信息添加到正在创建多例缓存中,创建完毕以后移除
- 如果当前Bean是其他类型,如Requtst,Session等类型,则自定义一个ObejctFacotry工厂,重写getObject方法,创建对象
- 对象创建以后,判断当前对象是否为自己需要的对象,如果是直接返回;如果不是进行类型转换,如果类型转换失败,直接抛异常
推荐阅读
- 安溪铁观音之知识大全,带你深入了解安溪铁观音茶叶
- 带你重新认识Linux系统的inode
- 一文带你了解Notta是什么
- CPU越来越热吗 一文带你看懂怎么选
- 带你实现一个静态服务器,超详细
- 江城国庆古茶山,带你走贺开古茶山
- 带你了解真正黑客入侵的常用手段及防护措施
- 42 张图带你揭秘后端技术都要学啥?
- 一篇文章带你了解HTML语法
- 贫血吃什么好 四款食谱带你远离贫血
