阿里开源技术

Spring IoC - Spring IoC 的设计

2019-10-14  本文已影响0人  Richard_易
image

前言

本文为解读Spring IoC 模块源码的开篇介绍。介绍Spring IoC 的相关概念与设计。

What is IoC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。

-- 摘自维基百科

大型应用中,需要多个类组合工作来实现业务逻辑。这使得每个对象都需要在工作的时候获取到与其合作的对象的引用。

如果这个获取过程要靠自身来实现,那么,代码会变得高度耦合并且难以测试。这对复杂的OOP系统的设计是非常不利的。

在OOP系统中,对象封装了数据和对数据的处理动作,对象的依赖关系体现在了对数据和方法的依赖上。这些依赖关系,可以通过把对象的依赖注入交给框架或IoC容器来完成。

简单来说:

这种从具体对象手中,交出控制的做法,在解耦代码的同时提高了代码的可测试性。好处具体如下:

  1. 不用自己组装,拿来就用。

  2. 享受单例的好处,效率高,不浪费空间。

  3. 便于单元测试,方便切换mock组件。

  4. 便于进行AOP操作,对于使用者是透明的。

  5. 统一配置,便于修改。

Spring IoC

在Spring中,IoC容器是实现这个模式的载体,它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方法调用的依赖。这种依赖注入是可以递归的,对象被逐层注入

就此而言,这种方案有一种完整而简洁的美感,它把对象的依赖关系有序地建立起来,简化了对象依赖关系的管理,在很大程度上简化了面向对象系统的复杂性。

Spring IoC提供了一个基本的JavaBean容器,通过IoC模式管理依赖关系,并通过依赖注入和AOP切面增强了为JavaBean这样的POJO对象赋予事务管理、生命周期管理等基本功能。

IoC 容器的设计

在Spring IOC 容器的设计当中,我们可以看到两个主要的容器系列(根据命名),

对于使用者来说,这些都是容器,是容器的不同表现形式,使用什么样的容器完全取决于使用者的需求。

undefined

BeanFactory

BeanFactory接口定义了IoC容器最基本的形式,并且提供了IoC容器所应该遵守的最基本的服务契约,同时,这也是我们使用IoC容器所应遵守的最底层和最基本的编程规范,这些接口定义勾画出了IoC的基本轮廓。

往下的整个继承树是蛮复杂的,你也不需要所有都掌握,就想我们之前提过的怎么学习源码,找核心类。现在来挑几个重点的BeanFactory说一下。避免后面源码分析章节会一脸懵逼。

以上接口,推荐大家去阅读一下他们的JavaDoc,来了解作者是怎么描述的。更为准确。

ApplicationContext

ApplicationContext是一个高级形态意义的IoC容器,ApplicationContext在BeanFactory的基础上集成了MessageSource, ApplicationEventPublisher, ResourcePatternResolver这几个接口,这些接口为ApplicationContext提供了以下BeanFactory不具备的新特性:

BeanDefinition

在这些Spring提供的基本IoC容器的接口定义和实现的基础上,Spring通过定义BeanDefinition来管理基于Spring的应用中的各种对象以及它们之间的相互依赖关系。

BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。

image.png

BeanDefinition抽象了我们对Bean的定义,是让容器起作用的主要数据类型。对IoC容器来说,BeanDefinition就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构,依赖反转功能都是围绕对这个BeanDefinition的处理来完成的。

这些BeanDefinition就像是容器里装的水,有了这些基本数据,容器才能够发挥作用。

结语

接下去的章节我们会正式开始分析Spring IoC 的具体实现,容器的初始化和依赖注入是怎么实现的。大部分都是源码解读的内容。

如果之前没有阅读源码经验的同学,可以先看看这篇你为什么要看源码?如何看源码?

参考

上一篇下一篇

猜你喜欢

热点阅读