从宏观角度分析Spring源码之IOC

今天是5月3号,烈日似火,热的让人喘不过气来。就在这个让人燥热的时刻我准备开始着手写Spring源码分析一系列文章。一是巩固自己的知识体系,二是分享一些技术心得给铁子们,让Spring技术原理通俗易懂的展现在大家面前,从此让世界上不再有不懂Spring原理的Java程序猿,让世界从此没有回答不上来的Spring技术面试。

这篇文章我们从Spring核心IOC切入,分析一下Spring中的IOC机制到底都干了些什么不可描述的事情。

1、概念

Inversion of Control是IOC的全称,即我们经常听到的控制反转,就是把Bean的控制权(创建、获取、依赖注入)交给了Spring容器。咱们日常写代码的时候经常会applicationContext.getBean("xxx"),这是从Spring容器中获取xxx,然后就可以使用xxx了。举个形象的例子来解释下控制反转:从前有一家四口,分别是老爸、老妈、儿子、儿媳,这一家子有个规矩,就是老爸、儿子、儿媳发工资必须要上交给老妈,用钱的时候跟老妈要,也就是一家子的财政大权交给了老妈管理,老妈负责统一调配钱的使用权,工资的控制权交给了老妈,这就是典型了控制反转案例。

2、IOC容器初始化流程

请问要把IOC容器初始化,总共分几步?根据我无数次翻阅代码的经验,我把IOC初始化简单分为三步。

(1)定位:定位配置文件和扫描相关注解

(2)加载:将配置信息载入到内存

(3)注册:根据载入的配置信息,将Bean初始化到容器中

3、源码分析IOC初始化流程

在进行源码阅读之前呢,首先要定位一个源码的阅读入口,曲径通幽,即ClassPathXmlApplicationContext类或AnnotationConfigApplicationContext类,不言而喻前者是xml配置文件驱动入口类,后者是注解驱动入口类。因为AnnotationConfigApplicationContext和ClassPathXmlApplicationContext相比较的话大同小异且相对简单,故我们以ClassPathXmlApplicationContext为例进行讲解。

上图是ClassPathXmlApplicationContext类中的构造方法,简单来说,IOC容器的初始化是由refresh()方法来启动的,调用这个方法预示着IOC容器的正式启动。

进入refresh()方法查看

 调用obtainFreshBeanFactory()方法进行Bean的配置读取并封装成Ioc的指定数据结构BeanDefinition。

由于IOC初始化调用链太长,所以直接上时序图是理解的最佳手段,铁子们可以根据我画出的时序图来做源码的跟踪阅读,时序图如下:

总体的调用过程如时序图所示, 简单的用语言描述下:Spring加载配置文件并解析,根据解析的结果扫描Bean,并将其封装成BeanDefinition以供Spring使用,接下来将遍历所有的BeanDefinition,将其put到beanDefinitionMap中,至此完成IOC的初始化。

Spring容器的初始化过程比较复杂,我们把主体思路抽离出来就很容易可以理解,因此,看源码的时候不要一头扎进入猛看,那样用不了5分钟就会晕车的,所以要学会抽丝剥茧,抽取框架中的主干代码进行分析即可。

下篇文章会进行Spring  DI(依赖注入)的分析,敬请期待!

猜你喜欢

转载自blog.csdn.net/qq_27324761/article/details/105903443