spring IoC容器简述
这个接口系统是以BeanFactory和ApplicationContext为核心的。
在理解spring ioc概念时,可以分两条线
BeanFactory和ApplicationContext
BeanFactory
spingIoC的基础容器实现
BeanFactory接口定义了IoC容器最基本的形式,并且提供了IoC容器所应该遵守的最基本的服务契约,同时,这也是我们使用IoC容器所应遵守的最底层和最基本的编程规范,这些接口定义勾画出了IoC的基本轮廓
DefaultListableBeanFactory、Xml-BeanFactory、ApplicationContext等都可以看成是容器附加了某种功能的具体实现,也就是容器体系中的具体容器产品。
从接口BeanFactory到HierarchicalBeanFactory,再到ConfigurableBeanFactory,是一条主要的BeanFactory设计路径。在这条接口设计路径中,BeanFactory接口定义了基本的IoC容器的规范。
而HierarchicalBeanFactory接口在继承了BeanFactory的基本接口之后,增加了getParentBeanFactory()的接口功能,使BeanFactory具备了双亲IoC容器的管理功能
来看看它的定义
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException; < T > T getBean(String name, Class < T > requiredType) throws BeansException;
Object getBean(String name, Object...args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;
Class getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
如果要扩展自己的容器产品,建议读者最好在继承体系中检查一下,看看Spring是不是已经提供了现成的或相近的容器实现供我们参考。
DefaultListableBeanFactory
实际上包含了基本IoC容器所具有的重要功能,也是在很多地方都会用到的容器系列中的一个基本产品。
在Spring中,实际上是把DefaultListable-BeanFactory作为一个默认的功能完整的IoC容器来使用的。XmlBeanFactory在继承了Default-ListableBeanFactory容器的功能的同时,增加了新的功能
XmlBeanFactory使用了DefaultListableBeanFactory作为基类,DefaultListable-BeanFactory是很重要的一个IoC实现,在其他IoC容器中,比如ApplicationContext,其实现的基本原理和XmlBeanFactory一样,也是通过持有或者扩展DefaultListableBeanFactory来获得基本的IoC容器的功能的。
参考XmlBeanFactory的实现,我们以编程的方式使用DefaultListableBeanFactory。从中我们可以看到IoC容器使用的一些基本过程。尽管我们在应用中使用IoC容器时很少会使用这样原始的方式,但是了解一下这个基本过程,对我们了解IoC容器的工作原理是非常有帮助的
//编程的方式使用DefaultListableBeanFactory
ClassPathResource res = new ClassPathResource("beans.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
- 创建IoC配置文件的抽象资源,这个抽象资源包含了BeanDefinition的定义信息。
- 创建一个BeanFactory,这里使用Default-ListableBeanFactory
- 创建一个载入BeanDefinition的读取器,这里使用XmlBeanDefinitionReader来载入XML文件形式的BeanDefinition,通过一个回调配置给BeanFactory
- 从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成。完成整个载入和注册Bean定义之后,需要的IoC容器就建立起来了。这个时候就可以直接使用IoC容器了
ApplicationContext
springIoC的容器的高级特性实现
以ApplicationContext应用上下文接口为核心的接口设计
我们常用的应用上下文基本上都是ConfigurableApplicationContext或者WebApplicationContext的实现
对于Application-Context接口,它通过继承MessageSource、ResourceLoader、ApplicationEventPub-lisher接口,在BeanFactory简单IoC容器的基础上添加了许多对高级容器的特性的支持。
提供了以下BeanFactory不具备的新特性:
- 支持不同的信息源。我们看到Application-Context扩展了MessageSource接口,这些信息源的扩展功能可以支持国际化的实现,为开发多语言版本的应用提供服务。
- 访问资源。这一特性体现在对ResourceLoader和Resource的支持上,这样我们可以从不同地方得到Bean定义资源。
因为具备了这些丰富的附加功能,使得ApplicationContext与简单的BeanFactory相比,对它的使用是一种面向框架的使用风格,所以一般建议在开发应用时使用ApplicationContext作为IoC容器的基本形式。
ApplicationContext应用上下文的主要功能已经在FileSystemXmlApplicationContext的基类AbstractXmlApplicationContext中实现,如果应用直接使用FileSystemXmlApplicationContext,对于实例化这个应用上下文的支持,同时启动IoC容器的refresh()过程。
对于FileSystemXmlApplicationContext:
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
这个refresh()过程会牵涉IoC容器启动的一系列复杂操作,同时,对于不同的容器实现,这些操作都是类似的,因此在基类中将它们封装好。所以,我们在FileSystemXml的设计中看到的只是一个简单的调用。