读《spring技术内幕》学Spring底层 第一部分

2.2 IOC容器系列的设计与实现:BeanFactory 和 applicationContext

Spring的IOC容器设计中,有两个主要的容器系列

一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本的功能;
另一个是ApplicationContext应用上下文,作为容器的高级形态而存在。在简单容器的基础上,增加了许多面向框架的特性,对应用环境作了许多的适配。

##2.2.1 spring的IOC容器系列
Spring的IOC容器系列Resource和它的子类
Spring包下的Resource接口
作为IOC容器,它的具体实现指定基本的功能规范,就是接口类BeanFactory,为用户使用的IOC容器所设定的最基本的功能规范。

在这里插入图片描述

Resource相当于水桶(IOC容器)BeanFactory定义了水桶最基本的功能。而Spring的的具体IOC容器需要满足BeanFactory这个基本的接口定义。

在spring提供IOC容器的接口定义和实现的基础上,Spring通过定义BeanDefinition管理基于Spring的应用中的各种对象以及它们之间的相互依赖关系。抽象了我们对Bean的定义,是让容器起作用的主要数据类型。

2.2.2 IOC容器的设计

接口路线1. BeanFactory到ConfigurableBeanFactory

在这里插入图片描述
BeanFactory: 定义了基本的IOC容器规范
HierarchicalBeanFactory:增加getParentBeanFactory的接口功能,具备双亲IOC容器的管理功能。
ConfigurableBeanFactory:主要定义了一些对BeanFactory的配置功能,如setParentBeanFactory设置双亲IOC容器,addBeanPostProcessor增加Bean后置处理器等。

接口路线2. ApplicationContext应用上下文接口为核心的接口设计

在这里插入图片描述
我们常用的应用上下文基本上都是ConfigurableAplicationContext和WebApplicationContext的实现。
ListableBeanFactory:细化了许多BeanFactory的接口功能,如getBeanDefinitionNames接口方法
ApplicationContext:通过继承许多接口,在BeanFactory简单IOC容器的基础上做了扩展。

BeanFactory的应用场景

用户使用容器时可以&来得到FactoryBean本身,用来区分通过容器来获取FactoryBean产生的对象和获取FactoryBean本身。
FactoryBean:IOC容器管理,但不是普通的Bean,而是一个能产生和修饰对象生成的工厂Bean。它的设计和工厂模式和修饰器模式类似。

getBean方法:通过名字来索引取得IOC管理的Bean,同时也可以对Bean的类型做检查。

有了BeanFactory的定义,用户可以执行以下的操作

  1. containsBean
  2. isSingleton
  3. isPrototype
  4. isTypeMatch Bean是否为指定类型
  5. getType 查询指定Bean的class类型
  6. getAliases 查询指定Bean的所有别名,在BeanDefinitions中定义的

XMLBeanFactory入手IOC设计原理

XMLBeanFactory
AbstracyBeanFactory -> AbstractAutowiredCapableBeanFactory -> DefaulistableBeanFactory-> XMLBeanFactory

DefaulistableBeanFactory: 是一个默认的功能完整的IOC容器,XMLBeanFactory继承于他,并且增加了读取XML文件方式定义BeanDefinition的方法。

XMLBeanFactory: 初始化了XMLBeanDefinitionReader来对XML文件进行信息处理的。构造XMLBeanFactory,需要指定BeanDefinition的信息来源,而这个信息来源需要封装成spring中的Resource类(就是上面所说的水桶)中给出,Resource是Spring用来封装I/O操作的类,例: ClassPathResource res = new classPathResource("bean.xml")

ClassPathResource: 用具体的ClassPathResource来构造Resource,将Resource作为构造参数传递给XMLBeanDefinition。使得IOC容器可以定位BeanDefinition完成容器的初始化和依赖注入的过程。

其代码如下

@Deprecated
@SuppressWarnings({"serial", "all"})
public class XmlBeanFactory extends DefaultListableBeanFactory {
	// XMLReader,有
	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);


	/**
	 * Create a new XmlBeanFactory with the given resource,
	 */
	public XmlBeanFactory(Resource resource) throws BeansException {
		this(resource, null);
	}

	/**
	 * 获取Resource对象,初始化XmlBeanDefinitionReader,调用loadBeanDefinitions传入Resource来初始化和加载Bean
	 */
	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}

}

编程式使用IOC容器

// 指定BeanDefinition地址
ClassPathResource res = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableFactory();
// 初始化Reader 
XMLBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanfinitions(res);

步揍如下

  1. 创建IOC配置文件的抽象资源,包含了BeanDefinition的定义信息
  2. 创建一个BeanFactory,这里使用DefaultListableBeanFactory
  3. 创建一个载入BeanDefinition的读取器XMLBeanDefinitionReader,回调配置给BeanFactory
  4. 从定义好的资源位置读入配置信息,具体的解析过程有XMLBeanDefinitionReader来完成,完成载入和注册Bean定义之后,IOC容器就建立起来了。

ApplicationContext的应用场景

除了上述的建立过程,为了方便客户使用,Spring已经提供了ApplicationContext为开发者使用,还为用户提供了附加服务。

在这里插入图片描述
提供的新特性

  1. 扩展了MessageSource接口,支持国际化实现
  2. 访问资源,支持ResourceLoader和Resource,可以从不同地方获取Bean定义。
  3. 支持应用事件,实现了ApplicationEventPublisher,在上下文引入事件机制,为Bean的管理提供便利。

FileSystemXmlApplicationContext的实现来学习ApplicationContext:
在这里插入图片描述
可以看到,AbstractApplicationContext实现了ConfigurableApplicationContext,其实现了ApplicationContext的基本功能。而FileSystemXmlApplicationContext作为一个具体的应用上下文,只需要实现基类AbstractApplicationContext和自身设计相关的两个功能。

如果一个应用直接使用FileSystemApplicationContext,对于实例化这个应用的上下文的支持,同时启动IOC容器的refresh()过程

  • 46
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值