Spring架构揭秘-IOC容器
IOC容器简介
IOC容器体系结构
容器组成部分
IOC容器工作机制
bean生命周期
容器加载管理的流程
Spring的IOC相当于spring的心脏,spring所有的功能都是围绕容器来进行扩展的。有人说spring的IOC容器不就是一个Bean工厂嘛,利用反射实例化java bean然后缓存起来。对于这种见解,笔者只能认为其认知十分肤浅。IOC是控制反转的简称,也叫做依赖注入,也就是说将Bean的控制权都交由Spring来管理,理想的情况下是完全基于接口编程,至于具体使用哪个实现类完全交由第三方来决定,从而达到业务与系统框架完美解藕的目的。
Spring的IOC不仅仅是完成了实例化Bean,它更多的是掌握Bean的控制权,IOC容器就像一台由各个精密的部件装配起来的高效运行的机器。下图揭示了IOC容器的组成部分。
由上图可以知道IOC容器主要由两部份组成,分别是BeanFactory和ApplicationContext。如果说BeanFactory是Spring的心脏,那么ApplicationContext就是Spring的躯干了。下面我们来具体看下BeanFactory和ApplicationContext。
Bean Factory体系
BeanFactory的这套继承体系堪称经典。BeanFactory主要的就是getBean(String beanName)方法获取Bean,接口本身并不关心获取的具体过程,就像我们只关心工厂能生产出什么产品,至于是如何生产,使用什么原料并不重要,因此这个基础的接口就达到了基础容器定义的目的。下面直接的就有三个子类接口,分别是
AutowireCapableBeanFactory:定义了容器中的Bean按照某种规则(名称、类型等)自动装配的方法
HierachicalBeanFactory:父子级联IOC容器接口,子容器可以根据该接口访问父容器
ListableBeanFactory:定义了访问容器中Bean基本信息的方法,该接口的实现通常会加载所有在Spring中定义的Bean。
在spring中最常使用的就是DefaultListableBeanFactory。下面来看看DefaultListableBeanFactory的继承体系
我们可以看到DefaultListableBeanFactory除了具备BeanFactory的功能,它还实现了SingletonBeanRegistry接口,也就是Bean在Spring中的存储器,相当于Spring中Bean的内存数据库。它除了缓存Bean实例还缓存了Bean定义,这对于后续执行Bean处理器非常有用。
至此我们就能大体的看出一个标准的容器所具有的功能和其内部的结构体系了,下面我们就来看看一个完整的容器ApplicationContext的结构体系
从上图可以知道ApplicationContext不仅仅具备了Bean容器的功能,同时它还拥有国际化组件和事件监听器组件的功能。在一个应用框架里,相对于Bean容器,ApplicationContext就完整了很多。在往下看看Application的继承体系,可以发现一个ApplicationContext可以发育成各种优雅且强大的应用框架。
从Application的继承体系中可以知道,它继承了 ListableBeanFactory, HierarchicalBeanFactory,于是就有了Bean Factory的基本功能同时还可以获取父容器。 然后还继承了 MessageSource,这是Spring中做国际化的顶层接口,Spring的设计者认为国际化是一个通用的组件,在系统信息输出的时候比如springMVC里的Controller,不同模块都有可能这些组件访问国际化信息,因此把Application与MessageSource结合起来就显得非常合理了。ApplicationContext还继承了 ApplicationEventPublisher,有了它以后ApplicationContext就可以发布事件并且允许注册事件监听器,使得Spring拥有一套比较完善的事件发布和监听机制。
再来看看ApplicationContext的子类,可以发现我们熟悉的ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,同时还有SpringBoot中使用的AnnotationConfigEmbeddedWebApplicationContext。这些实现可以满足了我们日常开发中web和非web环境下的开发需求。
Bean生命周期
下面来看看Spring Bean生命周期流程
由图可以看出来,在调用getBean()方法时,获取一个Bean之前需要经历执行初始化之前的逻辑,设置属性,设置方法,执行完成初始化后的动作然后将singleton的Bean放到缓冲池中,非singleton的就返回给client使用。在整个生命周期中BeanPostProcessor都扮演着重要的作用,事实上一个Bean在容器中需要经历哪些生命周期基本上由容器注册了哪些BeanPostProcessor来决定。