标签搜索

目 录CONTENT

文章目录

Spring源码解读(一):IOC

陈铭
2021-02-02 / 0 评论 / 0 点赞 / 508 阅读 / 1,548 字 / 正在检测是否收录...

Spring核心组件

Spring 框架的总体架构图

从下图中可以看出 Spring 框架中的核心组件只有三个:Core、Context 和 Beans。它们构建起了整个 Spring 的骨骼架构。没有它们就不可能有 AOP、Web 等上层的特性功能。下面也将主要从这三个组件入手分析 Spring。
image

三个核心组件的关系

Bean 包装的是 Object,而 Object 必然有数据,如何给这些数据提供生存环境就是 Context 要解决的问题,对 Context 来说他就是要发现每个 Bean 之间的关系,为它们建立这种关系并且要维护好这种关系。所以 Context 就是一个 Bean 关系的集合,这个关系集合又叫 Ioc 容器,一旦建立起这个 Ioc 容器后 Spring 就可以为你工作了。那 Core 组件又有什么用武之地呢?其实 Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些列的工具,从这个角度看来,Core 这个组件叫 Util 更能让你理解。

Bean组件

Bean的类型

前面已经说明了 Bean 组件对 Spring 的重要性,下面看看 Bean 这个组件式怎么设计的。Bean 组件在 Spring 的 org.springframework.beans 包下。这个包下的所有类主要解决了三件事:Bean 的定义、Bean 的创建以及对 Bean 的解析。对 Spring 的使用者来说唯一需要关心的就是 Bean 的创建,其他两个由 Spring 在内部帮你完成了,对你来说是透明的。

而创建的Bean,从比较粗放的角度来说,一个是FactoryBean接口实现的Bean,一个是通常广义上使用的JavaBean。

BeanFactory接口

实现这个接口的Bean也会被Spring所管理,这个Bean的职责就是产生其他Bean,它是个工厂类。简而言之,在Spring初始化工厂类时,就是在创建这个接口的实现类。

除此之外,Spring还提供了一个接口FactoryBean。它是一个简便的实现工厂模式的一个接口,也由Spirng帮我们管理。有时候我们想要获取初始化好的工厂类Bean,返回来的就是FactoryBean的实例。
image

BeanDefinition接口

除了工厂类Bean,其他的Bean都是被生产出来的。而且这些类都是实现上面这个接口(这个接口,也不是最顶层接口)。顾名思义,就是定义Bean各种信息数据的接口,Spring管理的非工厂类Bean也都拥有BeanDefinition接口所应该具备的Bean信息。

在创建IOC容器下的单例时,Spring就会Bean的BeanDefinition进行解析,解析又是由BeanDefinitionReader接口的实现类进行的,这里不做赘述。
image

小结

总而言之,我们只要知道,IOC容器中的Bean,大体分为两类:生产Bean的Bean和被生产的Bean。值得注意这两类Bean的继承体系十分复杂,远不仅仅我上述两个接口,上述两个接口只是比较具有代表性。

Context组件

ApplicationContext接口

Context维护了上述一系列Bean的生命周期,是应用的环境,也可以说成是IOC容器。

ApplicationContext是一个Context接口,它也继承了 BeanFactory,这也说明了 Spring IOC容器中运行的主体对象也是 Bean,另外 ApplicationContext 继承了 ResourceLoader 接口,使得 ApplicationContext 可以访问到任何外部资源,这将在 Core 中详细说明。

总体来说 ApplicationContext 必须要完成以下几件事:标识一个应用环境;利用 BeanFactory 创建 Bean 对象;保存对象关系表;能够捕获各种事件。

image

Core组件

Resource接口

Core的组件有很多,其中一个重要组成部分就是定义了资源的访问方式,也就是Resource接口。

Resource 接口封装了各种可能的资源类型,也就是对使用者来说屏蔽了文件类型的不同。对资源的提供者来说,如何把资源包装起来交给其他人用这也是一个问题,我们看到 Resource 接口继承了 InputStreamSource 接口,这个接口中有个 getInputStream 方法,返回的是 InputStream 类。这样所有的资源都被可以通过 InputStream 这个类来获取,所以也屏蔽了资源的提供者。
image

IOC容器如何工作

创建 BeanFactory 工厂

构建BeanFactory的入口就在 AbstractApplicationContext 类的 refresh 方法中。(AbstractApplicationContext是BeanFactory的抽象实现类)。看图中解释。
image

Bean实例化

实例化Bean又是在AbstractApplicationContext类的finishBeanFactoryInitialization方法中看图中解释。

随便提一下freezeConfiguration方法,这个是接口ConfigurableListableBeanFactory的方法,该接口的实现该方法的类就一个DefaultListableBeanFactory。其中这个实现类的freezeConfiguration方法会让this.configurationFrozen = true。

同时该类还有个方法isBeanEligibleForMetadataCaching,方法体就一句return this.configurationFrozen...,就是判断能不能缓存元数据。因此freezeConfiguration方法就是让Bean进行缓存的。
image

Bean关系建立

那么上面已经说清楚了BeanFactory和Bean这么建立的,现在就是我们怎么把这些Bean的关系建立起来,也就是把我们自己Bean注入成某个类的属性(IOC经典实现场景,比如:创建JDBC连接对象)

没图说不清楚,看图吧,我都整理好了。