(一)Spring IOC容器的设计与实现

控制反转

Spring IoCIoC全称是"Inversion of Control",译:控制反转数据结构

"控制反转"又称"依赖反转"编码

DI全称是"Dependency Injection",译:依赖注入设计

使用控制反转,依赖注入后,当建立对象时,由一个调度系统将其所依赖的对象的引用传递给它(这些对象也都来自于调度系统所管理的对象),即依赖被注入到对象中。因此,控制反转是关于一个对象如何获取它所依赖的对象的引用code

上述的调度系统是应用平台,具体来讲是IoC容器。经过使用IoC容器,对象依赖关系的管理被反转了,转到IoC容器中来了,对象之间的相互依赖关系由IoC容器进行管理,并由IoC容器完成对象的注入xml

IoC容器的核心数据结构

BeanDefinitionIoC容器的核心数据结构。又称"Bean定义信息"。是建立Bean实例时所使用的模板对象

Bean是容器管理的对象的统称blog

容器在建立Bean实例以前会先建立BeanDefinition对象,它保存了Bean的定义信息,例如Bean的名字,类型,是单实例仍是多实例,是否是懒加载,所依赖的其余对象有哪些等接口

IoC容器的设计与实现

IoC容器有两个系列生命周期

一个是实现BeanFactory接口的简单容器系列,这个系列的容器能实现容器的最基本的功能。又称"Bean工厂"事件

一个是实现ApplicationContext接口的高级容器系列,它是容器的高级形态。又称"应用上下文"或"上下文"。上下文在简单容器的基础上又增长了许多新功能

Spring IoC容器的设计

下面这张图描述的IoC容器的接口设计图,IoC容器的实现类就是以容器的接口设计为基础实现的

设计主线

  • BeanFactory为核心。从BeanFactoryHierarchicalBeanFactory再到ConfigurableBeanFactory。这是一条主要的BeanFactory类型容器的设计路线
  • ApplicationContext为核心。从BeanFactoryListableBeanFactoryApplicationContext,再到ConfigurableApplicationContextWebApplicationContext。咱们经常使用的上下文基本都是ConfigurableApplicationContextWebApplicationContext的实现类

咱们经常使用的BeanFactory的实现类是DefaultListableBeanFactory。同时,以这个实现类为基础,又有许多应用于不一样场景下的子类bean工厂。不过咱们一般直接使用DefaultListableBeanFactory

咱们经常使用的ApplicationContext的实现类是AbstractApplicationContext的子类。这个抽象类包含了容器的初始化方法refresh()

AbstractApplicationContext实现的是ConfigurableApplicationContext接口。

BeanFactory的设计原理

这些接口方法定义出了一个基本的IoC容器

  • boolean containsBean(String name);容器中是否有名为nameBean
  • String[] getAliases(String name);查询Bean的全部别名
  • getBean()有多个重载方法,是从容器中获取Bean实例的方法(此方法包含若是获取不到就建立一个Bean实例的流程)
  • boolean isSingleton(String name);返回Bean是不是单实例
  • boolean isPrototype(String name)返回Bean是不是多实例(Bean是单实例仍是多实例,这些信息保存在对应的BeanDefinition对象中)
  • ...

这些方法提供了容器最基本的功能

ApplicationContext的设计原理

ApplicationContext除了实现了BeanFactory外还实现了其余接口,为容器添加了其余功能

  • MessageSource信息源。支持国际化功能的实现
  • ResourceLoader访问资源。用于获取 Bean的定义信息所在的资源,为建立 BeanDefinition对象作准备
  • ApplicationEventPublisher发布事件。能够在上下文中,在Bean的生命周期中发布事件
  • ...

容器初始化流程

首先,由编码者使用某种形式编写Bean的配置信息,例如在.xml文件中写<bean>标签配置Bean

而后,启动容器进行初始化。容器初始化大体分三步

  1. BeanDefinitionResource定位(定位Bean配置信息所在位置)
  2. 载入BeanDefinition(建立BeanDefinition对象)
  3. 向容器注册BeanDefinition对象(在容器内部将对象put到一个容器持有的map对象中)

在第一次调用容器的getBean()方法(BeanFactory中定义的方法)获取Bean对象时,若是对象还未被实例化,就获取对应的BeanDefinition对象,并使用它做为模板建立实例对象

再容器完成初始化后,调用refresh()方法刷新容器。方法执行完后容器即可以使用

ps:容器初始化的流程可能在refresh()方法外执行,也可能在refresh()方法内执行

相关文章
相关标签/搜索