三条路线告诉你如何掌握Spring IoC容器的核心原理
一、前言
前三篇已经从历史的角度和大家一起讨论了为什么会有Spring,Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国。本节的主要目的就是通过一个切入点带大家一起学习一下Spring IoC的核心原理,正如从历史的角度出发讲述为什么会有Spring一样,希望通过这个切入点能让你轻松的掌握住Spring IoC的核心原理。
本篇文章假设你已经可以熟练的用Spring了,因而对于某一个细节如何实现的不会在进行详细的阐述!
二、IoC和DI的基本概念
IoC(控制反转,英文含义:Inverse of Control)是Spring容器的内核,AOP、事务等功能都是建立在此基础上的。从字面意思上可以把IoC拆分为两层含义:控制和反转。控制可以了解为是接口实现类的选择权,反转可以了解为这个选择权交给第三方进行管理;总的来说就是某一接口具体实现类的选择控制权从调使用类中移除,转交给第三方进行决定,即由Spring容器通过Bean配置来进行控制,这样的话应使用程序本身就不使用负责依赖对象的创立和维护,而由Spring容器进行管理。
虽然我们现在对IoC的基本概念都已经熟读与心了,但是在老一辈的时候,IoC的概念还不是很容易被人了解。在那个年代,业界的一位大佬,软件界泰斗级的人物Martin Fowler提出了DI(Dependency Injection,依赖注入)的概念,来代替IoC。
依赖注入的概念和控制反转的概念从本质上是一样的,只是从不同的侧面形容了这个功能。依赖注入的概念形容的是让调使用类对某一接口实现类的依赖关系有第三方容器或者其余东西注入,以此来移除对某一接口实现类的依赖。

时至今日,我们常说的IoC/DI的时候也是把依赖注入和控制反转作为同一个概念来进行阐述的!
三、从哪里入手IoC容器?
我曾尝试过很屡次,想踏进Spring原理的大门,但是一次次都被毫无头绪的开端而打退!后来逐步翻阅少量书籍逐步形成了那么一点点思路,接下来主要按着我的思路讨论一下Ioc容器的基本原理。
正如我们学习骑自行车一样,开始的时候都是先看别人如何骑的,而后自己才能慢慢的学会(当然发明自行车的人是天才)。学习Spring原理也是一样,只有掌握了基本的Spring的用,才有可能踏进Spring原理的大门。因而,这里我们从如何用开始哪?
1、首先看一下项目结构

继承关系:

bean的配置:

Main代码如下:

2、相信每一个学习Spring的小伙伴都是从上述的方式学起的,上图中最显眼的两个类就是红色圈圈出的,也设置我们在最开始用到的,用UML工具显示最基本的类图关系:

庞大的一个继承和实现体系!看到这里大致上也就是我要说的第二条路线了(下文会详细详情)!这条路线向我们展现了从Spring最接近使用开发人员用的ClassPathXmlApplicationContext、FileSystemXmlApplicationContext类到Spring的顶层接口之间层层的继承和实现关系。
看到这里我们似乎还是毫无头绪,这就需要我们借鉴前人的经验了,这个经验就是如何正确的了解BeanFactory和ApplicationContext之间的关系。
四、BeanFactory和ApplicationContext之间的关系
我们都知道Spring是通过配置文件、注解、Java类等方式形容Bean与Bean之间的依赖关系,利使用Java的反射功能实例化Bean并建立Bean与Bean之间的依赖关系;
这些底层的工作正是由Spring IoC容器完成的,除此之外Spring IoC容器还提供了Bean实例缓存、生命周期管理、时间发布等高级服务。
而这里要说的BeanFactory和ApplicationContext都作为Spring IoC容器的形态存在,只不过有些许区别而已,简单的来说:(1)BeanFactory接口的实现类是一个简单容器系列,该系列的容器只实现了容器最基本的功能;(2)ApplicationContext接口的实现类是一个高级容器系列,该系列的容器在简单容器的基础上添加了很多面向框架的特性,对应使用环境做了很多适配,同时增加了很多面向应使用的功能,例如:国际化支持和框架事件体系结构等。
通常情况下,我们习惯称BeanFactory为Ioc容器,而称ApplicationContext为应使用上下文,有时候我们还直接称ApplicationContext为Spring容器。
至此,我应该可以引出我要说的前两条路线:第一条路线是基于BeanFactory的简单容器系列;第二天路线是基于ApplicationContext的高级容器系列;
五、第一条路线:基于BeanFactory的简单容器系列
既然BeanFactory的实现类也是一个容器,那么我们就应该可以用它来注入我们的Bean和获取我们的Bean,如何用哪?请看代码:

(1)创立IoC配置文件的笼统资源,这个笼统资源包含了BeanDefinition的定义信息(也就是我们在bean.xml文件中配置的一个bean的数据结构);?
(2)创立一个BeanFactory,这里用的是DefaultListableBeanFactory;?
(3)创立一个载入BeanDefinition的读取器,这里用的是XmlBeanDefinitionReader来载入XML形式的BeanDefinition,通过一个回调配置给BeanFactory;?
(4)从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成。
上述的过程,完成了整个载入和注册Bean的定义之后,我们所需要的IoC容器就建立起来了,这个时候我们即可以直接用IoC容器了。
上述代码中用了DefaultListableBeanFactory?这个BeanFactory默认实现的容器完成了Bean的注入和获取操作,查看其继承和实现关系如下:

BeanFactory位于接口类结构的顶端,它主要定义了IoC容器中应该具备的基本特性,主要接口定义如下,根据名称即可以看出是什么作使用,这里不再逐个解释:

面对如此多的接口或者类,我们应该如何了解哪?举个栗子,就像一辆汽车一样,BeanFactory中定义了这辆汽车应该具备的基本功能,通过层层的接口继承和实现为这个基本的汽车架构定制了很多特性,比方:可以座几个人,能否可以倒车等,一直到最后才形成了一辆基本可以正常用的汽车,但到这一步还是一个比较粗糙的产品或者者半成品。(可以用,但对于普通使用户不会直接用)
而关于这些接口或者类的详情,因为篇幅有限,这里不再逐个详情,主要给大家提供一种思路,如何顺藤摸瓜,掌握第一条了解Spring IoC容器的路线。
总的来说,BeanFactory是Spring框架的基础设置,面向的是Spring本身,下文中讲述的第二条路线其中也是用到了上述代码中的过程,我们在实际的开发中很少会直接用基于BeanFactory的简单容器系列。
六、第二条路线:基于ApplicationContext的高级容器系列
相对于第一条路线中的汽车半成品来说,第二个路线下的产品才真正算是一辆可以开的出去的汽车,在基于ApplicationContext的高级容器系列下为汽车新添加了很多特性,比方:加了电子档位、加了倒车雷达、全景天窗、全液晶显示器什么的,一直到最后才形成了一辆可以用的汽车(可以用,普通使用户也可以直接用)。

从上图中可以看出来,相对于BeanFactory来说ApplicationContext添加了很多新特性,例如MessageSource接口、ApplicationEventPublisher接口等,所以说ApplicationContext是一个高级形态意义上的IoC容器。
ApplicationContext的主要实现类是ClassPathXmlApplicationContext、FileSystemXmlApplicationContext,前者是通过从类路径加载配置文件,后者模式从文件系统中装载配置。
七、第三条路线:基于WebApplicationContext的Web容器系列
从上边的详情我们应该已经看出来了,不论是第一条路线还是第二条路线都是基于Java应使用的,而我们用最多的是JavaWeb应使用,这也是接下来要说的第三条路线:基于WebApplicationContext的Web容器系列。

WebApplicationContext是专门为Web应使用准备的,因为Web应使用比一般的Java应使用拥有更多的特性,因而WebApplicationContext扩展了ApplicationContext。

我们在配置Spring集成Spring MVC的时候基本都会用上述的方式配置Spring容器,ContextLoaderListener通过Web容器上下文参数contextConfigLocation获取Spring配置文件的位置。假如只是用Xml配置的Bean的话,会用WebApplicationContext的实现类XmlWebApplicationContext。
八、总结
本文的目的并不是详细的阐述Spring IoC容器的核心原理,这是由于市面上已经有很多书讲述Spring IoC容器的核心原理的,并且简单的一篇文章很难说清楚这么多的内容,这里主要是是希望通过将Spring IoC容器的核心原理内容进行划分,整理为3条基本路线,这样的话逐渐击破,才能使自己不会被庞大的代码结构体系所吓到!
在这里顺便给大家推荐一个架构交流群:617434785,里面会分享少量资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 三条路线告诉你如何掌握Spring IoC容器的核心原理