IOC原理解读(二)

IOC原理解读(二)

继上篇

今天解读的是:

    基于xml配置的bean的IOC过程中的实例化跟依赖注入原理。

xml配置文件spring-bean.xml内容如下:

IOC原理解读(二)_第1张图片

在加载完各个bean的definition到一个beanDefinitionMap后,是如何实例化bean呢?

先看看那些地方在需要获取bean definition,从这里找入口

1、查看获取definition的方法是哪被调用的

IOC原理解读(二)_第2张图片

在AbstractBeanFactory类中看到具体调用

IOC原理解读(二)_第3张图片

然后在doGetBean方法中找到了

IOC原理解读(二)_第4张图片
IOC原理解读(二)_第5张图片

然后终于找到了 是AbstractBeanFactory 类中的 getBean(String name) 是真正调用的地方

IOC原理解读(二)_第6张图片

然后在AbstractApplicationContext中找到了调用

IOC原理解读(二)_第7张图片

同类中调用

IOC原理解读(二)_第8张图片

同类中调用(beanFactory 在refresh方法中始终贯穿)

IOC原理解读(二)_第9张图片

看到这,我们大致知道了,实例化bean跟依赖注入的流程

Spring IoC容器对Bean定义资源的载入是从 AbstractApplicationContext 的 refresh() 函数开始的

refresh()是一个模板方法,refresh()函数的作用在于:在创建Ioc容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在refresh之后使用的是新建立起来的IoC容器。

refresh的作用类似于对IoC容器的重启,在新建立好的容器中对容器进行初始化,对Bean定义资源进行载入。

AbstractApplicationContext

IOC原理解读(二)_第10张图片

refresh中的具体步骤

1、准备刷新此上下文;

2、告诉子类刷新内部bean工厂;

3、准备bean工厂以便在此上下文中使用;

4、允许在上下文子类中对bean工厂进行后处理;

5、调用上下文中注册为bean的工厂处理器;

6、注册拦截bean创建的bean处理器;

7、为此上下文初始化消息源;

8、为此上下文初始化事件多主机;

9、初始化特定上下文子类中的其他特殊bean;

10、检查侦听器bean并注册它们;

11、实例化所有剩余(非lazy init)单例;

IOC原理解读(二)_第11张图片

   第二个参数false代表,这次加载的没有排除单例的bean定义,根据这些bean的名字,获取bean,实例化bean,并且在实例化过程中完成依赖注入

12、最后一步:发布对应事件;


下面我们看看具体是如何对bean进行实例化,然后完成依赖注入的

先看是如何完成所有需要实例化对象的实例化的

doGetBean方法

//这里是实际取得Bean的地方,也是触发依赖注入的地方

先不着急,看看具体实例化是如何操作的(也就是doGetBean())?逐个实例化

IOC原理解读(二)_第12张图片

如果有依赖的对象,那么将依赖的对象全部实例化!直到逐层依赖的对象,全部创建成功为止。

getBean是依赖注入的起点,之后会调用createBean,下面我们分析createBean的代码

IOC原理解读(二)_第13张图片

doCreateBean方法

IOC原理解读(二)_第14张图片

createBeanInstance方法

IOC原理解读(二)_第15张图片

跟随上面的步伐,上面实例化的时候调用了instantiateBean方法,该方法代码如下:

IOC原理解读(二)_第16张图片

我们重点关注 getInstantiationStrategy() 这个方法,可以看到instantiateBean方法的功能实现是通过调用getInstantiationStrategy().instantiate方法实现的。 

getInstantiationStrategy 方法的作用是获得实例化的策略对象,也就是指通过哪种方案进行实例化的过程。继续跟踪下去我们可以发现,Spring当中提供了两种实例化方案: BeanUtils 和 Cglib 方式。

BeanUtils实现机制是通过Java的反射机制,Cglib是一个第三方类库采用的是一种字节码加强方式机制。 

Spring中采用的默认实例化策略是Cglib。 

重点关注如下方法

IOC原理解读(二)_第17张图片

如果没有重写,则不要用cglib重写类

其他地方没有改变当前对象的方法逻辑(没有被重写)

存在重写的方法就用Cglib

为什么?

正确解释如下:跟lookup-method注入和replace-method注入有关 见:

https://www.smwenku.com/a/5b9959102b717757338f4b18/

https://blog.csdn.net/lyc_liyanchao/article/details/82432993


Java 反射机制 创建对象

IOC原理解读(二)_第18张图片

使用Cglib API 实例化对象

IOC原理解读(二)_第19张图片
IOC原理解读(二)_第20张图片

然后讲解注入依赖

看了上面的代码后,我们应该重点关注 createBeanInstance() 和 populateBean() 这两个方法。其中,populateBean() 开始 就是注入依赖

注入依赖

IOC原理解读(二)_第21张图片

1、填充bean对象

2、暴露对象;

IOC原理解读(二)_第22张图片

至此,终于完成了 实例化、依赖注入

你可能感兴趣的:(IOC原理解读(二))