7000字长文带你深入了解IOC启动原理

1. IOC概述1.1 是什么?
两个概念:控制反转,依赖注入
来看一下传统的干活方式:在对象单一职责原则的基础上,一个对象很少有不依赖其他对象而完成自己的工作,所以这个时候就会出现对象之间的依赖 。而体现在我们的开发中,就是需要什么对象的时候,就创建什么对象,此时对象创建的控制权在我们自己手里 。当对象创建的太多的时候,就会出现一个对象更改,就得更改所有依赖它的对象,耦合性大 。自主性体现的同时也出现了对象耦合严重的情况 。

  • 这个时候,我们就会思考,能不能我们在用的时候直接拿到这个对象去用,而将创建对象的能力交给第三方,这样我们就不需要关心对象是怎么创建的了 。即将自己的控制权交出去 。这就是控制反转
  • 这个时候,就会有另一个问题产生了,对象怎么才能直接被我们拿来用呢 。对象创建的时候,我们把这个对象注入到这个对象中,然后就可以使用了 。这就是依赖注入
  • 另一个问题,耦合性怎么被解决掉的?通过控制反转我们仅仅使用了这个对象,如果对象发生了修改,我们仅仅需要修改第三方创建对象的方式即可,这个时候难道还会出现所谓的对象耦合吗?
2. IOC架构
7000字长文带你深入了解IOC启动原理

文章插图
 
一个图搞定,这个就是IOC的架构思路,这不是其执行流程图 。
我们接下来一步一步来解读 。
2.1 白话版
在第一章中我们了解了IOC是来帮助我们管理和创建对象的 。
这个时候我们需要一个承载我们需要创建信息的容器,即图中的XML或者注解,那么有了我们自己的BeanDefiniton信息以后,我们需要一个接口用来读取这些信息,于是出现了BeanDefinitionReader用来读取我们自己的Bean信息 。
那么我们需要考虑一个问题了,那么多的对象怎么生产呢?
答案就是工厂模式 。Spring默认的工厂是DefaultListableBeanFactory,没错,Spring中的所有对象(容器对象和我们自己创建的对象)都是由他创建的 。大批量生产对象
这个时候又有了一个问题,我们不想通过BeanFactory直接生产了,需要对这个工厂进行一些特定处理,于是出现了BeanFactoryPostProcessor,用来对工厂做一些特定的处理 。我们自己可以通过实现这个接口,进行自定义BeanFactory 。又有兄弟说了:我想单独创建一些我喜欢的对象,安排,FactoryBean诞生了,它可以帮助我们创建一个我们需要的对象(第四部分详细解释他们之间的区别) 。
那又有兄弟说了:我想让统一的对象创建之前按照我的方式进行一些特殊的行为,简单,安排:see_no_evil
BeanPostProcessor出现了,他提供了两个方法:一个在对象实例化之后初始化之前,执行内部的Before方法,在初始化之后,执行After方法 。(Bean生命周期,第四部分详解)
这个时候有兄弟有疑问了,不是说BeanPostProcessor在创建对象之前执行吗?怎么是创建完毕以后才执行的Before方法 。
如果各位兄弟了解过指令重排序这个概念,那么一定会听过一个案例,创建一个对象需要三步
  • 创建空间(实例化)
  • 初始化
  • 赋值
其中在初始化和赋值会出现指令重排序
根据这个点,应该可以get到一个点,实例化和初始化不一样 。
所以又引出了一个点,我们对Bean进行一些操作,怎么操作,肯定是修改属性,或者添加一些属性等等,需要等待其在堆中开辟空间即实例化完成以后执行吧 。
所以BeanPostProcessor的before方法在实例化之后执行,初始化之前执行 。
经历过前面一大堆的操作以后,终于我们的对象进入我们兜里了(容器里) 。
关于销毁,一般情况下我们通过ApplicationContext拿不到其销毁方法,只能通过其子类实现获取,关于销毁同样的流程,先执行一个销毁之前的操作,然后再销毁 。
其中在初始化和赋值会出现指令重排序
根据这个点,应该可以get到一个点,实例化和初始化不一样 。
所以又引出了一个点,我们对Bean进行一些操作,怎么操作,肯定是修改属性,或者添加一些属性等等,需要等待其在堆中开辟空间即实例化完成以后执行吧 。
所以BeanPostProcessor的before方法在实例化之后执行,初始化之前执行 。
经历过前面一大堆的操作以后,终于我们的对象进入我们兜里了(容器里) 。
关于销毁,一般情况下我们通过ApplicationContext拿不到其销毁方法,只能通过其子类实现获取,关于销毁同样的流程,先执行一个销毁之前的操作,然后再销毁 。


推荐阅读