SpringSpring IOC设计思路
Posted 幽灵雾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSpring IOC设计思路相关的知识,希望对你有一定的参考价值。
【设计思路_理念】
一、为什么要做(Why)
Spring IOC的本质,就是我们如果需要一个对象实例(Bean),找Spring要,Spring就会给我们,我们不需要关注这个实例是怎么来的,与使用者解耦,方便使用。
二、要做什么(What)
所以,作为Spring,面对有人来找我要对象实例(Bean),那就有两种选择:
- 第一种,是我生产一个给你;
- 第二种,是把我已经生产好,存在仓库里的找到,然后给你用;
Spring最初的设计思路应该是第一种,直接帮你生产一个对象,所以就有了一个描述这个工厂的接口:BeanFactory。为什么会称为factory也是因为此,但后续为了追求利用率和效率,则更多的偏向于第二种方式。
BeanFactory这个接口也成为SpringIOC中最为基础底层的一个口,定义了IOC工厂的最基本规范,例如获取Bean实例的方法getBean。
三、如何开展(How)
有了BeanFactory,Spring的设计可以开展了:
Spring项目,它最先做的事:是定义一套工厂的生产标准。
这很符合欧美人的风格,先把螺丝、螺母的标准定好,至于哪些人、在哪里建自己的工厂生产这些螺丝、螺母,都按他们统一的标准来即可,这样能保证无论哪家工厂生产出来零件都可以灵活通用。
目前Spring自己按照自己的标准实现了一整套功能完整且稳定的IOC,同时很多规模较大的企业,也在这套标准和完整IOC的基础上,对于部分模块和功能进行了满足自己要求的定制化实现。
【设计思路_标准/规范】
然而,这个基本的IOC工厂BeanFactory,提供的功能比较单一,所以又派生出了带有各种特殊功能的工厂接口:
1、spring-beans包中提供
为了丰富和管理BeanFactory的工厂规范如下:
HierarchicalBeanFactory:在BeanFactory的基础上,增加了getParentBeanFactory方法,提供了了层级式IOC容器管理的功能。
ListableBeanFactory:在BeanFactory的基础上,增加了批量获取BeanDefinition(Bean的结构定义,相比Bean来说类似于类和对象)的能力。
AutowireCapableBeanFactory:在BeanFactory的基础上,为第三方框架提供了支持,提供了获取、构建和管理其他框架Bean实例的功能。
ConfigurableBeanFactory:在HierarchicalBeanFactory的基础上,增加了配置BeanFactory的各种方法,以及存取共享单例Bean的功能(由SingletonBeanRegistry提供)。
ConfigurableListableBeanFactory:在ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory三者的基础上,增加了
例如忽略依赖、冻结Bean配置的功能。
2、spring-context包中提供
上面还都属于较为简单的工厂规范,下面这位就比较高级了:
ApplicationContext:在HierarchicalBeanFactory、ListableBeanFactory的基础上,增加了:
获取系统属性、环境变量的功能(由EnvironmentCapable提供);
信息的国际化、参数信息替换的功能(由MessageSource提供);
事件发布功能(ApplicationEventPublisher提供);
解析各种资源文件的功能(ResourcePatternResolver提供);
ConfigurableApplicationContext:在ApplicationContext的基础上,增加了:
对ApplicationContext生命周期的管理功能(由Lifecycle提供);
对ApplicationContext的关闭功能(由Closeable提供);
对ApplicationContext的配置、管理、刷新等功能;
3、spring-web包中提供:
这些是为Web项目提供的功能较为全面的工厂规范:
WebApplicationContext:在ApplicationContext的基础上,增加了获取Web公共信息ServletContext(Servlet中的信息类)的功能。
ConfigurableWebApplicationContext:在WebApplicationContext, ConfigurableApplicationContext的基础上,增加了配置ServletContext等Web信息的各种方法。
4、spring-boot包提供:
还有其他很多派生接口规范,例如:
spring-boot包中提供:
ReactiveWebApplicationContext:SpringBoot基于ApplicationContext的封装。
ConfigurableWebServerApplicationContext:SpringBoot基于ConfigurableApplicationContext、WebServerApplicationContext的封装。
ConfigurableReactiveWebApplicationContext:SpringBoot基于ConfigurableApplicationContext, ReactiveWebApplicationContext的封装。
5、其他:
还有提供spring-boot-test包中提供的为测试使用的规范接口,这里不做详解:
AssertableApplicationContext、
AssertableWebApplicationContext、AssertableReactiveWebApplicationContext、
ApplicationContextAssertProvider等
【设计思路_官方实现】
既然Spring已经制定了一整套工厂相关的标准/规范,那么有谁来按照这个标准去实现这个工厂呢?Spring官方已经给出了一套相对成熟完美的实现。
首先,我们从现阶段使用最多的SpringBoot的启动来说,debug并跟踪任意SpringBoot的启动过程:
会发现run中初始化了一个AnnotationConfigServletWebServerApplicationContext的ApplicationContextContext,向上追溯他的父类,直到GenericApplicationContext,发现GenericApplicationContext中有一个变量,这个beanFactory就是为我们生产和管理bean的工厂了 :
private final DefaultListableBeanFactory beanFactory;
我们看一下DefaultListableBeanFactory的父级层次:
可以看到DefaultListableBeanFactory逐层实现了ConfigurableListableBeanFactory接口,分别实现了:
- 由DefaultSingletonBeanRegistry带来对单例Bean实例、Bean别名的注册、管理能力(通过实现SingletonBeanRegistry、AliasRegistry而具备能力);
- 由FactoryBeanRegistrySupport带来对FactoryBean的注册、管理和获取能力(【Spring】FactoryBean和普通Bean的区别);
- 由AbstractBeanFactory带来最为核心的getBean能力(即为用户提供所需产品的能力),以及配置BeanFactory的能力(通过实现ConfigurableBeanFactory而具备能力);
- 由AbstractAutowireCapableBeanFactory带来对第三方Bean的创建、属性渲染、装配、初始化等能力(通过实现AutowireCapableBeanFactory而具备能力);
- 由DefaultListableBeanFactory本身带来了对Bean进行实例化等能力(通过实现ConfigurableListableBeanFactory而具备能力)
这些实现的细节,我们会在SpringBoot的启动流程中详细说明
【总结】
SpringIOC的设计思路,需要关注如下几点:
- IOC提供的是生产对象的能力,而不单单是存取对象;(所以才会成为Factory,而不是Container)
- IOC首先是提供了一套标准(一整套接口),然后还提供了一整套的实现;
- IOC标准设计拆分的很细致,几乎能够做到一个功能一个接口的程度,这一点有好有坏:好在扩展性强、隔离性强,坏在理解成本高,实现成本高;
以上是关于SpringSpring IOC设计思路的主要内容,如果未能解决你的问题,请参考以下文章