Spring探索: IOC容器的实现 一

零:认识BeanDefinition

    在面向对象程序设计中,我们以"对象"来作为问题空间与解空间中一对一映射关系的抽象。BeanDefinition类就是ioc容器中,对依赖反转模式中管理的对象之间依赖关系的数据抽象,简单来说:它抽象了spring对Bean的定义,用来管理基于spring的应用中的各种对象,以及对象之间的相互依赖关系。

一:BeanFactory接口清单

BeanFactory定义了IOC容器的最基本形式,提供了IOC容器应该遵循的最基本服务契约。

105050_BE6f_1417725.png

getBean 方法是ioc容器的主要方法,可以获取ioc容器中管理的Bean

containsBean 判断容器中是否含有指定name的bean

isSinglton 查询指定name的bean是否为单例模式

isPrototype 查询指定name的bean是否为原型模式(多实例)

                (isSinglton和isPrototype可以在BeanDefinition中通过setScope来指定)

isTypeMatch 查询指定name的Bean的class类型是否与特定的class类型匹配

getType 查询指定name的bean的class类型

getAliases 查询指定name的Bean的所有别名(返回string[]),别名可以通过BeanDefinition定义

-----------------------------------------------------------------------------------------------------

二:XmlBeanFactory

XmlBeanFactory是一个可以读取以xml文件方式定义的BeanDefinition的ioc容器

111725_IEfu_1417725.png

在xmlBeanFactory中初始化一个XmlBeanDefinitionReader对象,用它来处理以xml方式定义的BeanDefinition,xmlBeanFactory并不直接参与处理。

xmlBeanFactory的构造器中,我们可以看到Resourse对象,Resourse对象是spring用来封装io操作的类,在此它为xmlBeanFactory指定了XmlBeanDefinitionReader的信息来源。

111709_0QTS_1417725.png

XmlBeanFactory继承自DefaultListableBeanFactoryspring把DefaultListableBeanFactory作为一个默认的功能完整的ioc容器来使用,它实际包含了基本ioc容器所具有的重要功能。xmlBeanFactory在其基础上扩展出了处理xml信息的方法。

 从这个我们可以看到ioc容器使用的基本过程应该是:

1:创建ioc配置文件的抽象资源。(包含BeanDefinition)

2:创建一个BeanFactory。

3:创建一个载入BeanDefinition的读取器(如XmlBeanDefinitionReader),并通过回调配置给BeanFactory。

4:讲定义好的资源位置读入配置信息,具体的解析过程由具体的读取器来完成。完成载入和注册bean信息后,就可以通过ioc容器直接使用了。

-----------------------------------------------------------------------------------------------------

三:ApplicationContext

132639_Vo6N_1417725.png

ApplicationContext在BeanFactory的基础上添加了更多功能,可以说是一个高级形态的ioc容器,也是我们最常用的。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {...}

ApplicationContext增加的特性:

    1:支持不同的信息源。从上面代码中可以看到,ApplicationContext扩展了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现,为开发多语言版本应用提供服务。

    2:访问资源。我们可以从不同的地方得到Bean定义资源,尤其是从不同的I/O途径获得Bean的定义信息。这一特性体现在对ResourceLoader和Resource的支持上。(ApplicationContext接口的实现类都继承了DefaultResourceLoader)

    3:支持应用事件。继承ApplicationEventPublisher接口,该接口在上下文中引入了事件机制,为Bean的管理提供便利。

    4:其他附加的服务。

ApplicationContext容器的设计原理

134157_iUUI_1417725.png

我们在研究applicationContext设计原理时,以实现类FileSystemXmlApplicationContext为例。

public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {...}

134633_1jFh_1417725.png

134700_BHuJ_1417725.png

上图可以看到:FileSystemXmlApplicationContext中只包含了与它自身设计相关的两项功能,而其他功能都已经由他的父类AbstractXmlApplicationContext实现了。

	public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

第一个功能:在FileSystemXmlApplicationContext的构造器中,调用了启动ioc容器的refresh() 方法,这个方法牵扯到ioc容器启动的一系列复杂动作,同时,对于不同的容器实现这些动作都是类似的,所以在基类(AbstractApplicationContext)中将他们封装好,此处仅进行调用。

@Override
	protected Resource getResourceByPath(String path) {
		if (path != null && path.startsWith("/")) {
			path = path.substring(1);
		}
		return new FileSystemResource(path);
	}

另一个功能:实现了从文件系统中加载xml的Bean定义资源。这部分是他设计的具体相关内容。通过他可以为读取xml文件上保存的BeanDefinition做准备(仅是做准备,并非直接处理,因为不同的应用上下文实现对应着不同的读取beanDefinition方式),此处仅得到FileSystemResourse定位资源。

总结:

                1:顶层(相对顶层)接口定义通用契约

                 2:其他分支接口对顶层契约进行扩展,

                 3:用抽象类实现接口,对接口方法进行部分实现(也可全部实现,根据需求判断)。此时,若这个抽象类的具有多个子类,则可以把子类间存在分歧的部分写成抽象方法。而多个子类中相同的部分则集中由这个抽象类来进行实现。(如果仅仅只有一个子类,那么并不需要抽象类来对接口进行过滤,可以直接用一个类来实现接口,但是考虑到系统扩展的可能性,仍然建议这样做。)

                4:抽象类的子类,仅仅定义与其功能设计相关的部分,但并不对相关功能进行实现,实现功能的动作被分配到其他执行者中。(因为可能会有多种不同的执行者)

转载于:https://my.oschina.net/dlam/blog/806477

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值