Spring 5.X 版本发布已经有一段时间了,网上也有一些资料但大部分都只是做了部分功能的简单介绍,没有全面系统的剖析,鉴于这种情况笔者决定抱着试一试的心态,花上较长一段时间来对Spring 5.X版本做一个全面的介绍并且从源码角度较为深度的剖析,同时融入自己的一些观点,一些内容的理解也都是靠笔者自己的经验,如果某些地方理解的有误或者有偏差的地方,欢迎广大读者指正,共同进步
对于Spring框架我相信搞java的同学应该没有不知道的,一问起它的作用,大家估计都不用动脑子就可以喊出来,IOC和AOP,我这里提出一个问题?你真的理解这两个方面的内容吗?或者除了这两个方面,对Spring你还知道哪些?听到这个话,如果你心跳加快了的话,就请把心沉下来,我们从现在开始对Spring做一个全面的了解,Let's do it!
咱们先来看一下Spring框架的总体概览,以此来了解一下Spring到底有哪些玩意儿。
做事有理有据,打开Spring 的说明文档我们来一探究竟
https://docs.spring.io/spring/docs/5.0.9.RELEASE/spring-framework-reference/index.html
我们可以用下面这张图来进行表示

咱们由下至上一个模块一个模块的学习
一、Core Container
我们带着以下几个问题来学习Spring 的 Core Container(以下简称容器)
1、什么是Spring 容器?Spring 容器有什么作用?有哪些Spring 容器?
带着上面的问题同时结合Spring 说明文档以及参考Spring源码我们来寻找一下这些问题的答案
Spring的官方文档“Container overview”是这么定义的:
The interface org.springframework.context.ApplicationContext represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the aforementioned beans
顺着这个思路我们结合Spring源码来看一下,这段话中的ApplicationContext到底是什么东西(至于如何查看Spring源码笔者在这里就不多做累述了,本文以5.0.8.RELEASE源码作为参考)
一、探秘ApplicationContext

上图为ApplicaitonContext的源码,ApplicationContext其实就是一个接口,接口只能用来定义行为,那么我们不妨来看一下它到底有哪些行为,笔者梳理了一下ApplicationContext的层级关系

1、ApplicationContext是位于org.springFramework.context包下的一个顶级接口
EnvironmentCapable、 ListableBeanFactory、HierarchicalBeanFactory、MessageSource、ApplicationEventPublisher、ResourcePatternResover
EnvironmentCapable:获得Environment对象,Environment对象定义了获得属性的方法,即此接口的主要目的是获得bean的属性
ListableBeanFactory、HierarchicalBeanFactory:这两个都继承BeanFactory,即在BeanFactory的基础上拓展了一些功能,BeanFactory中主要是getBean函数,其中有多种重载形式,由此可见BeanFactory定义了如何获取Bean实例对象
MessageSource:这个接口定义了getMessage()函数,主要作用是获取消息或者信息
ApplicationEventPublisher: 此接口定义了注册事件的若干方法
ResourcePatternResolver:此接口继承自ResourceLoader接口,主要定义了如何获取资源以及得到资源对象
ApplicationContext:继承自上面的所有接口,可见它具有上面接口所定义的所有行为,同时自身也做了一些拓展,如getId、getDisplayName等
至此我们简单的了解了一下ApplicationContext的层级关系,由此我们大致可以知道这个ApplicationContext具有以下功能:
1、可以获取Bean实例,因为BeanFactory及其子接口和父接口
2、可以获取bean的属性,因为EnvironmentCapable
3、可以注册事件,即拥有事件处理机制,因为ApplicationEventPublisher
4、可以处理配置资源,因为ResourcePatternResolver
5、拥有获取和处理消息机制,因为MessageSource
至此我们对ApplicationContext对象有了一个初步印象,但是单单只有接口是没有什么意义的,我们需要了解上面定义的这些行为是否实现了以及怎么实现的,接下来我们围绕着上面的功能对ApplicationContext进行进一步的探索
1、获取Bean实例,要了解这个功能我们从BeanFactory这个顶级接口开始,笔者梳理了BeanFactory的层级关系(BeanFactory是位于prg.springFramework.beans.factory包下的一个顶级接口)

到此我们梳理了BeanFactory的层级关系(实现表示继承,虚线表示实现,两行表示接口,三行表示类)
BeanFactory、HierarchicalBeanFactory、ListableBeanFactory我们已经了解过了这里就不做累述
ConfigurableBeanFactory:这个接口继承自HierarchicalBeanFactory接口,同时自身也拓展了一些功能,主要作用是对1、BeanFactory实例的配置 2、对Bean对象的管理 3、配置类加载器等
AbstractBeanFactory:这是一个抽象类,它实现了ConfigurableBeanFactory接口,这个类应该是我们关注的重点,因为它实现了ConfigurableBeanFactory及其父接口的所有行为,同时由于是一个抽象类它还可以定义自己的行为,稍后我们将进一步来学习这个类,看看它是实现类接口中的哪些行为
AutowireCapableBeanFactory:这个接口继承自BeanFactory接口,主要是定义了自动装配的一些行为
ConfigurableListableBeanFactory:这个接口继承自ListableBeanFactory,AutowireCapableBeanFactory, ConfigurableBeanFactory这三个接口主要作用是综合三个接口同时拓展自身解析资源对象并转换成内部对象,其中BeanDefinitiongetBeanDefinition(String beanName)是很重要的一个函数,它将配置数据转换成java内部对象BeanDefinition,稍后我们会详细讲解
AbstractAutowireCapableBeanFactory:这个抽象类继承自AbstractBeanFactory,同时实现了ConfigurableListableBeanFactory接口,它是对容器内部bean管理的行为实现
DefaultListableBeanFactory:这是一个最终实现类,即它代表了BeanFactory实例,它也是BeanFactory的默认实现,对BeanFacotory的操作实际上就是操作这个类,它拥有上面所述的所有接口的具体实现,稍后我们会进一步详细讲解
至此我们了解了BeanFactory的层级结构,也对BeanFactory实例有了一个大致的了解,现在我们可以做一个简单的小结:
1、ApplicationContext是BeanFactory的子接口,即它拥有BeanFactory所有的功能同时还拥有自己的拓展功能
2、DefaultListableBeanFactory是 BeanFactory的默认实现,它可以解析元数据配置来构建内部对象,即Beanfactory就是IOC容器
3、通过对层级的分析我们可以了解Spring这个设计模式实际上是采用了“抽象工厂模式”,即通过构建工厂类来灵活的定义自身的行为,同时也不会影响到其他类的实现,读者应该仔细体会这其中的方便之处
4、IOC容器的作用就是将资源转为内部对象同时定义一系列的行为来对容器内的对象进行管理
至此BeanFactory我们做了一个大致的了解,下面我们继续看一下ApplicationContext的层级关系,笔者梳理了ApplicationContext的层级关系

以上是ApplicationContext的层级关系(ApplicationContext父类接口的层级关系上面我们已经讲过了,这里就不再累述)
ConfigurableApplicationContext:这个接口继承自ApplicationContext,同时它还继承了Lifecycle, Closeable接口所有它具有运行状态和开启关闭功能,它自身还拓展了ApplicationContext接口,主要是1、新增了后置处理器接口 2、添加了监听 3、新增了refresh函数
AbstractApplicationContext:这个抽象类实现了ConfigurableApplicationContext接口,同时自身还拓展了如closeBeanFactory和refreshBeanFactory这样的接口,稍后我们将进一步探讨这个类的具体实现原理
AbstractRefreshableApplicationContext:这个抽象类继承自AbstractApplicationContext,它实现了AbstractApplicationContext中定义的行为,以它为分界,很好的将内置容器进行分类
GenericApplicationContext:这个一个实体类,它几乎涵盖了所有的IOC的可实现方式,可以使用xml配置也可以使用注解配置
AbstractRefreshableConfigApplicationContext:继承自AbstractRefreshableApplicationContext它新增了资源路径处理接口
AbstractXmlApplicationContext:这个抽象类继承自AbstractRefreshableConfigApplicationContext,它实现了资源路径加载和处理接口同时定义了获得资源对象的接口
一下的实现类都是ApplicationContext的具体实现类,即也代表了IOC容器的六种内置实现,不同的情况可以对应选择不同的容器进行加载
ClassPathXmlApplicationContext:可以根据资源路径的相对路径启动容器
FileSystemXmlApplicationContext:可以根据资源的绝对路径启动容器
AnnotationConfigApplicationContext:可以通过注解模式来启动容器
StaticApplicationContext:可以使用消息对象
GenericXmlApplicationContext:通用的xml文件格式来启动容器
GenericGroovyApplicationContext:可以通过Groovy形式来启动容器
至此Spring IOC容器我们已经有了一个比较全面的认识,接下来我们把BeanFactory和ApplicationContext放在一起做一个小结:
BeanFactory和ApplicationContext都是IOC容器的代表,但BeanFactory只提供了容器的基本功能,其他的功能需要手动添加;ApplicationContext继承自BeanFactory,同时它还拥有自己的拓展功能,还定义了几种内置容器供使用,所有ApplicationContext可以说是IOC容器的升级版,在使用过程中首选的就是ApplicationContext容器
好,我们现在回到开始时候的那个问题,什么是Spring 容器?Spring 容器有什么作用?有哪些Spring 容器?相信大家现在应该可以很好的回答这个问题了
我用自己的理解回答了一下:
1、什么是Spring 容器?
容器是通过配置、读取配置、实例化对象来构建和管理对象的过程
2、Spring 容器有什么作用?
读取配置、实例化对象来构建和管理对象
3、有哪些Spring 容器它们之间有什么区别?
BeanFactory和ApplicationContext,至于区别上面一段话我们已经总结了
4、Spring 容器的原理是什么?
我们下一篇继续讨论。。。。。
网友评论