Spring IoC - Spring IoC 的设计

前言

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

What is IoC

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

-- 摘自维基百科编程

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

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

在OOP系统中,对象封装了数据和对数据的处理动做,对象的依赖关系体如今了对数据和方法的依赖上。这些依赖关系,能够经过把对象的依赖注入交给框架或IoC容器来完成。oop

简单来讲:源码分析

  • 控制:当前对象对其内部成员对象的控制权/获取组装对象的过程
  • 反转:上述的过程/控制权,交由专门的第三方组件(容器或者说平台)来管理

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

  1. 不用本身组装,拿来就用。
  2. 享受单例的好处,效率高,不浪费空间。
  3. 便于单元测试,方便切换mock组件。
  4. 便于进行AOP操做,对于使用者是透明的。
  5. 统一配置,便于修改。

Spring IoC

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

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

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

IoC 容器的设计

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

  • 实现了BeanFactory接口的简单容器系列,只实现了容器的最基本功能;
  • ApplicationContext应用上下文,容器的高级形态,增长了许多面向框架的特性和对应用环境的适配;

对于使用者来讲,这些都是容器,是容器的不一样表现形式,使用什么样的容器彻底取决于使用者的需求。

undefined

BeanFactory

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

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

  • ListableBeanFactory,这个 Listable 的意思就是,经过这个接口,咱们能够获取多个 Bean,你们看源码会发现,最顶层 BeanFactory 接口的方法都是获取单个 Bean 的。
  • ApplicationContext 继承了 HierarchicalBeanFactory,Hierarchical 单词自己已经能说明问题了,也就是说咱们能够在应用中起多个 BeanFactory,而后能够将各个 BeanFactory 设置为父子关系。
  • AutowireCapableBeanFactory 这个名字中的 Autowire 你们都很是熟悉,它就是用来自动装配 Bean 用的,可是仔细看上图,ApplicationContext 并无继承它,不过不用担忧,不使用继承,不表明不可使用组合,若是你看到 ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory() 就知道了。
  • DefaultListableBeanFactory,在Spring中,其实是把DefaultListableBeanFactory做为一个默认的功能完整的IoC容器来使用的。包含了基本IoC容器所具备的重要功能。

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

ApplicationContext

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

  • 支持不一样的信息源。咱们看到ApplicationContext扩展了MessageSource接口,这些信息源的扩展功能能够支持国际化的实现,为开发多语言版本的应用提供服务。
  • 访问资源。这一特性体如今对ResourceLoader和Resource的支持上,这样咱们能够从不一样地方获得Bean定义资源。这种抽象使用户程序能够灵活地定义Bean定义信息,尤为是从不一样的I/O途径获得Bean定义信息。
  • 支持应用事件。继承了接口ApplicationEventPublisher,从而在上下文中引入了事件机制。这些事件和Bean的生命周期的结合为Bean的管理提供了便利。
  • 在ApplicationContext中提供的附加服务。这些服务使得基本IoC容器的功能更丰富。由于具有了这些丰富的附加功能,使得ApplicationContext与简单的BeanFactory相比,对它的使用是一种面向框架的使用风格,因此通常建议在开发应用时使用ApplicationContext做为IoC容器的基本形式。

BeanDefinition

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

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

image.png

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

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

结语

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

若是以前没有阅读源码经验的同窗,能够先看看这篇你为何要看源码?如何看源码?

参考

相关文章
相关标签/搜索