Spring IOC概念及体系结构

1,019 阅读4分钟

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」。

IOC与DI

IOC(控制反转)概念

平时在开发程序的时候,每个对象在使用它的合作对象时都要自己主动去创建这个合作对象,需要时就主动创建出来,创建权在自己手里,但是这种方式耦合度就很高;在使用Spring之后,将对象的创建权交给Spring容器来处理,所谓的控制就是将对象创建控制权交给了容器来创建,即容器控制了对象的创建,起初依赖对象的创建时对象主动创建,是正转,而反转就是将依赖对象的创建及注入给Spirng容器处理,对象只是被动的接受依赖对象。

注入方式

在IOC中,为被注入对象提供被依赖对象有三种方式:构造方法注入,setter注入,接口注入

DI(依赖注入)概念

容器动态的将依赖关系注入到组件中,容器实例化对象的时候主动将它依赖的类注入给它

IOC的体系结构

设计结构图

image.png

下面对结构图进行简要分析,来理解这个接口设计图

第一条接口设计主线是从BeanFactory到HierarchicalBeanFactory再到ConfigurableBeanFactory,BeanFactory定义了基本方法,例如getBean()等,HierarchicalBeanFactory增加了getParentBeanFactory接口功能,使BeanFactory具备了双亲IOC容器的管理功能;ConfigurableBeanFactory主要定义了一些对BeanFactory的配置功能,例如setParentBeanFactory()设置双亲IOC容器,通过addBeanPostProcessor()配置Bean后置管理器等;通过这些接口设计的叠加,定义了BeanFactory就是简单IOC容器的基本功能

第二条设计主线是以ApplicationContext为核心的接口设计,从BeanFactory到ListableBeanFactory再到ApplicationContext,再到我们常用的WebApplicationContext或者ConfigurableApplicationContext。L在这个接口体系中ListableBeanFactory和HierarchicalBeanFactory两个接口,连接BeanFactory接口定义和ApplicationContext应用上下文的接口定义。在ListableBeanFactory接口中,细化了许多BeanFactory接口功能,例如getBeanDefinitionNames()方法;对于ApplicationContext接口,它通过继承MessageSource,ResourceLoader,ApplicationEventPublisher,在BeanFactory简单IOC容器的基础上添加了许多对高级容器的特性支持。

Resource体系

org.springframework.core.io.Resource,它的每一个实现类都代表了一周资源的访问策略,例如

ClassPathResource、RLResource、FileSystemResource 等。

image.png

ResourceLoader 体系

有了资源之后,就要对资源进行加载,Spring就是利用ResourceLoader来进行统一的资源加载

image.png

BeanFactory体系

BeanFactory提供的是最基本的IOC容器的功能,并且提供了IoC容器所应该遵守的最基本的服务契约;BeanFactory只是一个接口,而例如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContet等都可以提供具体的实现。

image.png

BeanFactory基本方法

  • containsBean(String name)方法可以根据名字判断是否还有此名字的Bean

  • isSingleton(String name)方法可以根据名字判断是否是单例的Bean

  • isPrototype(String name)方法可以根据名字判断是否是多例的Bean

  • isTypeMatch(String name, Class<?> typeToMatch)方法可以根据名字的Bean的Class类型是否是特定的Class类型

  • getType(String name)方法查询指定名字的Bean的Class类型

  • getAliases(String name)查询 该指定名字所有的Bean的别名

BeanFactory容器的设计原理

BeanFactory接口提供了使用IOC容器的基本接口规范,Spring还提供了符合这个IOC容器的一系列容器进行具体实现;通过XmlBeanFactory的实现为例进行说明:

image.png

从图中可以看到类之间的联系

image.png

从源码可知,XmlBeanFactory继承自DefaultListableBeanFactory,XmlBeanFactory新增了读取XML文件的方法

image.png

XmlBeanFactory就是通过这个方法进行xml读取,方法传参需要Resource做为参数进行传递,对xmlBeanDefinitionReader对象初始化,以及使用这个对象来完成对loadBeanDefinitions的调用

BeanDefinition体系

用来描述Spring中的Bean对象。

image.png

BeanDefinitionReader体系

读取Spring配置文件内容,并将其转成IOC容器内部的数据结构:BeanDefinition

image.png

ApplicationContext体系

image.png

ApplicationContext除了能够提供前面介绍的容器的基本功能,还为用户提供了BeanFactory不具备的新特性

  • 支持不同的信息源。ApplicationContext扩展了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现

  • 访问资源:我们可以通过Resource来得到不同地方的Bean定义资源

  • 支持应用事件:继承了接口ApplicationEventPublisher,从而在上下文中引入了事件机制

ApplicationContext容器的设计原理

我们通过FileSystemXmlApplicationContext的实现为例来说明ApplicationContext的设计原理

FileSystemXmlApplicationContext有两个重要的功能

  • 一个功能是应用直接使用FileSystemXmlApplicationContext,对于实例化这个应用上下文支持,同时启动IOC容器refresh()过程。这在FileSystemApplicationContext的代码实现中可以看到:

image.png

这个refresh()过程会涉及IOC容器启动的复杂操作,关于这个reresh()在IOC容器启动时的具体表现,在后面再进行详细分析

  • 另一个功能是与怎样从文件系统中加载XML的Bean定义资源有关。

实现代码如下:

image.png

调用这个方法,可以得到FileSystemResource的资源定位