1、设计介绍
在Spring IOC 容器的设计中,有两个主要的容器系列,一个是实现Beanfactory接口的简单容器系列,这系列容器只实现了容器的最基本功能。另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在。
第一设计主线
从接口BeanFactory 到HierarchicalBeanFactory 再到ConfigurableBeanFactory,是一条主要的BeanFactory设计路径。在这条接口设计路径中,BeanFactory接口定义了基本的IOC容器规范。包括了getBean()这样获得Bean 接口。
HierarchicalBeanFactory 增加getParentBeanFactory接口的功能,使得BeanFactory具备了双亲IOC容器的管理功能。
ConfigurableBeanFactory 增加了一些配置功能,比如通过setParentBeanFactory 设置双亲IOC容器,通过增加addBeanPostProcessor 配置bean的后置处理器。
第二条设计主线
以ApplicationContext 应用上下文接口为核心的接口设计,这些设计的主要接口有:从BeanFactory 到ListableBeanFactory,再到ApplicationContext,再到ConfigureApplicationContext或者WebApplicationContex接口。
我们常用的上下文都是ConfigureableApplicationContext或者webApplicaitonContext的实现。
在这个接口体系中ListableBeanFactory和HierarchicalBeanFactory 两个接口是连接Beanfactory接口和ApplicationContext应用上下文的接口定义。
在ListableBeanFactory 细化了很多BeanFactory的接口功能,比如定义了getBeanDefinitionNames() 接口方法。
ApplicationContext接口 它通过继承MessageSource、ResourceLoader ApplicationEventPublisher接口,在BeanFactroy简单IOC容器的基础上增加了许多对高级容器的特性的支持。
BeanFactory中定义的接口方法:
通过接口方法containsBean让用户能够判断容器是否含有指定名字的Bean。
通过接口方法isSingleton来查询指定名字的Bean是否是Singleton类型的Bean。
对于Singleton 属性,用户可以在BeanDefinition中指定。
通过接口方法isPrototype 来查询指定名字的Bean 是否是Prototype 类型,这个属性也是在BeanDefinition中指定。
通过接口方法IisTypeMatch 来查询指定了名字的Bean的Class 类型是否是特定的Class类型。
通过接口方法getType来查询指定名字的Bean的Class类型
通过接口方法getAliases 来查询指定了名字的Bean的所有别名,这些别名都是用户在BeanDefinition中定义的。
2、BeanFactory的设计原理
以XmlBeanFactory 的实现为例来说明简单IOC容器的设计原理。
XmlBeanFactory是IOC容器的最底层实现,它是在继承DefaultListableBeanFactory的基础上,增加了处理XMl定义的bean信息的容器。在XmlBeanFactory 是以XmlBeanDefinitonReader对象来完成的。 在XmlBeanFactory 首先需要得到Resource对象,对XmlBeanDefinitionReader
对象的初始化,以及使用这个对象来完成对loadBeanDefinition的调用,就是这个调用启动从Resource中载入BeanDefinition的过程,LoadBeanDefinition同时也是IOC容器初始化的重要组成部分。
我们以编程的方式使用DefaultListableBeanFactory。
代码如下:
ClassPathResource res = new ClassPathResource("Bean.xml");
DefaultListableBeanFactory factory = new DefaultListabelBeanFactory();
XmlBeanDefintionReader reader = new XmlBeanDefintionReader(factory);
reader.loadBeanDefintions(res);
总结步骤如下:
创建IOC配置文件的抽象资源,这个抽象资源包含了BeanDefintion的定义信息。
创建一个BeanFactory 。
创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefintionReader来载入Xml文件形式的BeanDefinition,通过一个回调配置给BeanFactory。
从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成。完成整个载入和注册Bean定义之后,需要的IOC容器就建立起来了。
ApplicationContext的应用场景:
ApplicationContext增加的功能:
支持不同的信息源 通过扩展接口MessageSource实现。
访问资源。 这一特性体现在ResourceLoader和Resouce的实现上,这样我们就可以从不同的地方得到Bean定义资源。
支持应用事件 通过继承接口ApplicaitonEventPublisher实现。
在ApplicatonContext提供的附加服务。
我们以FileSystemXmlApplicationContext的实现来说明ApplicationContext的设计原理。
在FileSystemXmlApplicationContext的设计中,我们看到ApplicationContext应用上下文的主要功能已经在它的基类AbstractXmlApplicationContext中实现了。 在FileSystemXmlApplicationContext中作为一个具体应用上下文,只需要实现和它自身设计相关的两个功能。
一个功能是,实例化FileSystemXmlApplicationContext时,需要启动IOC容器的refresh过程。
另一个功能是从文件中读取以xml形式存在的BeanDefinition做准备。