Spring IOC容器实现分析.docx
《Spring IOC容器实现分析.docx》由会员分享,可在线阅读,更多相关《Spring IOC容器实现分析.docx(73页珍藏版)》请在三一办公上搜索。
1、Spring IOC容器实现分析Spring IOC容器实现分析 准备工作 我们都知道,IOC容器和AOP是Spring框架的核心,To the developer, for the developer and by the developer - 简化JAVA企业应用的的开发是Spring框架的目标,为更好的使用IOC容器,我们结 合Spring IOC的源代码对它的实现作一个分析。在了解IOC容器实现的基础上,Spring的使用者可以跟 好的使用IOC容器和Spring框架,同时如果需要对Spring框架作自己的扩展,这些方面的了解也是很有 必要的。我们在这里假设读者已经具备对Spring
2、 IOC容器使用的基本知识 - 关于对Spring IOC容器的 使用,可以参考以下的参考资料,这里就不对一些使用和配置的问题多做讲解了。 Spring Framework Reference Guide Spring In Action Expert One-on-one J2EE Development without EJB Professional Java Development with the Spring Framework 还需要准备好Spring的源代码,我们这里用的代码是Spring2.0,当然了一个可以查看源代码的编辑器 也是需要的,这里使用的是Eclipse3.2 -
3、 很多说明性的图例都是直接从屏幕拷贝下来的。下面是一些文 章中用到的专有词汇: 上下文:ApplicationContext Bean定义信息:BeanDefinition Bean工厂:BeanFactory 工厂Bean:FactoryBean 单件:Singleton 概述:基本IOC容器和上下文 因为IOC容器为应用开发者管理对象之间的依赖关系提供了很多便利和基础服务,所以业界有许多IOC 容器供开发者选择,Spring Framework就是其中的一个。对Spring IOC容器的使用来说,我们常常接 触到的Bean工厂和上下文就是IOC容器的表现形式,在这些Spring提供的基本I
4、OC容器的接口定义和 实现的基础上,我们通过定义Bean定义信息来管理应用中的对象依赖关系。 在使用Spring IOC容器的时候,了解Bean工厂和上下文之间的区别对我们了解Spring IOC容器是比 较重要的。从实现上来看,IOC容器定义的基本接口是在Bean工厂定义的,也就是说Bean工厂是 Spring IOC容器的最基本的形式,很显然,BeanFactory只是一个接口类,没有给出IOC容器的实现, 只是对IOC容器需要提供的最基本的服务做了定义,象我们下面看到的 DefaultListableBeanFactory,XmlBeanFactory, ApplicationConte
5、xt这些都可以看成是IOC容器 的某种具体实现。看看Bean工厂是怎样定义IOC容器的基本服务的: public interface BeanFactory /这里是对工厂Bean的转义定义,因为如果使用bean的名字检索IOC容器得到的对象是工厂Bean 生成的对象, /如果需要得到工厂Bean本身,需要使用转义的名字来向IOC容器检索 String FACTORY_BEAN_PREFIX = &; /这里根据bean的_名字,在IOC容器中得到bean实例,这个IOC容器就象一个大的抽象工厂,用户可 以根据名字得到需要的bean /在Spring中,Bean和普通的JAVA对象不同在于:
6、/Bean已经包含了我们在Bean定义信息中的依赖关系的处理,同时Bean是已经被放到IOC容器中 进行管理了,有它自己的生命周期 Object getBean(String name) throws BeansException; /这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根 据名字取得的bean实例的Class类型和需要的不同的话。 Object getBean(String name, Class requiredType) throws BeansException; /这里提供对bean的检索,看看是否在IOC容器有这个名字的b
7、ean boolean containsBean(String name); /这里根据bean名字得到bean实例,并同时判断这个bean是不是单件,在配置的时候,默认的 Bean被配置成单件形式,如果不需要单件形式,需要用户在Bean定义信息中标注出来,这样IOC容器在 每次接受到用户的getBean要求的时候,会生成一个新的Bean返回给客户使用 - 这就是Prototype形 式 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; /这里对得到bean实例的Class类型 Class getTyp
8、e(String name) throws NoSuchBeanDefinitionException; /这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String getAliases(String name); 这个BeanFactory接口为IOC容器的使用提供了使用规范,在这个基础上,Spring还提供了它符合这个 IOC容器接口的实现供开发人员使用,比如XmlBeanFactory和各种常见的上下文,我们先看一下 XmlBeanFactory这个IOC容器的实现,和那些上下文相比,它提供了基本的IOC容器的基本功能;我们 可以认为直接的BeanFactory的
9、实现是IOC容器的基本形式,而各种上下文的实现是IOC容器的高级表 现形式。XmlBeanFactory的实现是这样的: public class XmlBeanFactory extends DefaultListableBeanFactory /这里为容器定义了一个默认使用的bean定义读取器,在Spring的使用中,Bean定义信息的读取是 容器初始化的一部分,但是在实现上是和容器的注册以及依赖的注入是分开的,这样可以使用灵活的 bean定义读取机制。 private final XmlBeanDefinitionReader reader = new XmlBeanDefinition
10、Reader(this); /这里需要一个Resource类型的Bean定义信息,实际上的定位过程是由Resource的构建过程来完 成的。 public XmlBeanFactory(Resource resource) throws BeansException this(resource, null); /在初始化函数中使用读取器来对资源进行读取,得到bean定义信息。这里完成整个IOC容器对 Bean定义信息的载入和注册过程 public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws Be
11、ansException super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); 我们看到XmlBeanFactory使用了DefaultListableBeanFactory作为它持有的IOC容器实现,在这个 基础上,添加了XML形式的Bean定义信息的读取功能。从这个角度看,这个 DefaultListableBeanFactory是很重要的一个Spring IOC实现。下面我们可以看到上下文也和 XmlBeanFactory一样,通过持有这个DefaultListableBeanFactory来获得基本的I
12、OC容器的功能。通 过编程式的使用DefaultListableBeanFactory我们可以看到IOC容器使用的一些基本过程: ClassPathResource res = new ClassPathResource(beans.xml); DefaultListableBeanFactory factory = new DefaultListableBeanFactory; XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(res); 这些代码
13、演示了以下几个步骤: 1. 创建IOC配置文件的抽象资源 2. 创建一个BeanFactory,这里我们使用DefaultListableBeanFactory 3. 创建一个载入bean定义信息的读取器,这里使用XmlBeanDefinitionReader来载入XML形式 的bean定义信息,配置给BeanFactory 4. 从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成,这 样完成整个载入和注册bean定义的过程。我们的IoC容器就建立起来 这个基本过程我们可以看到,IOC容器建立的基本步骤,这些我们可以编程式的完成这些配置,但在
14、Spring中,它提供的上下文已经为我们作了这些事情,所以从这个角度说上下文是一个高级形态上的 IOC容器。更方便了用户的使用,相比于那些基本的IOC容器的BeanFactory实现,上下文除了提供基本 的上面看到的容器的基本功能外,还为用户提供了以下的附加服务更方便的让客户使用容器: 可以支持不同的信息源,我们看到ApplicationContext扩展了MessageSource 访问资源, 体现在对ResourceLoader和Resource的支持上面,这样我们可以从不同地方得到 bean定义资源,这样用户程序可以灵活的定义Bean定义信息 支持应用事件,继承了接口Applicatio
15、nEventPublisher,这样在上下文中引入了事件机制而 BeanFactory没有 在上下文环境中,这些上下文提供的基础服务更丰富了基本IOC容器的功能。所以一般我们建议客户使 用上下文作为IOC容器来使用 - 和XmlBeanFactory一样,上下文是通过持有 DefaultListableBeanFactory这个基本的IOC容器实现来提供IOC容器的基本功能的,这一点可以在 下面我们分析IOC容器的初始化过程中看得很清楚。 IOC容器和上下文的初始化 简单来说,IOC容器和上下文的初始化包括Bean定义信息的资源定位,载入和注册过程。在上面编程式 的使用DefaultLista
16、bleBeanFactory中我们可以大致的看到上述过程的实现。值得注意的是,Spring 把这三个过程的完成分开并让不同的模块来完成,这样可以让用户更加灵活的对这三个过程来进行剪 裁,定义出自己最合适的IOC容器的初始化。比如Bean定义信息的资源定位由ResourceLoader通过统 一的Resource接口来完成,这个Resource接口对各种形式的资源信息的使用提供了统一的接口,比如 在文件系统中的Bean定义信息可以使用FileSystemResource,在类路径中可以使用上面看到的 ClassPathResource等等。第二个关键的部分是Bean定义信息的载入,这个载入过程就
17、是把用户定义 好的Bean表示成IOC容器内部的数据结构的过程,在下面我们可以看到这个数据结构就是 BeanDefintion,下面我们会对这个载入的过程做一个详细的分析;第三个过程是向IOC容器注册这些 Bean定义信息的过程,这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的,这个注册 过程把载入过程中解析得到的Bean定义信息向IOC容器中进行注册 - 在IOC容器内部往往使用一个象 HashMap这样的容器来持有这些Bean定义。 值得注意的是,IOC容器和上下文的初始化一般不包含Bean的依赖注入的实现,关于依赖注入实现的过 程在下面也会进行详细的分析。
18、好了,下面我们详细的看一看IOC容器和上下文的Bean定义信息的资源 定位,载入和注册过程是怎么实现的。 Bean定义信息的资源定位 在上面编程式使用DefaultListableBeanFactory的时候,我们可以看到首先定义一个Resource来定位 容器使用的Bean定信息: ClassPathResource res = new ClassPathResource(beans.xml); 这个定义的Resource并不是让DefaultListableBeanFactory直接使用,而是让 BeanDefinitionReader来使用,这里我们也可以看到使用上下文对于直接使用 De
19、faultListableBeanFactory的好处,因为在上下文中的使用中,Spring已经为我们提供了一系列具 备Resource功能的实现,比如我们常看到的 FileSystemXmlApplicationContext,ClassPathXmlApplicationContext,XmlWebApplicationContext, 我们下面就看看FileSystemXmlApplicationContext是怎样完成这个资源定位过程的,先看看这些类 的继承体系: 可以看到,这个FileSystemXmlApplicationContext已经通过继承具备了ResourceLoader
20、: public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext /通过这个字符串数组可以持有多个资源位置 private String configLocations; public FileSystemXmlApplicationContext(String configLocation) throws BeansException this(new String configLocation); /这里是一系列初始化函数,得到Resource在文件系统中的位置,并通过refresh来初
21、始化整个IOC 容器 /这个refresh调用时容器的初始化调用入口 public FileSystemXmlApplicationContext(String configLocations) throws BeansException this(configLocations, null); public FileSystemXmlApplicationContext(String configLocations, ApplicationContext parent) throws BeansException super(parent); this.configLocations = c
22、onfigLocations; refresh; public FileSystemXmlApplicationContext(String configLocations, boolean refresh) throws BeansException this(configLocations, refresh, null); public FileSystemXmlApplicationContext(String configLocations, boolean refresh, ApplicationContext parent) throws BeansException super(
23、parent); this.configLocations = configLocations; if (refresh) refresh; protected String getConfigLocations return this.configLocations; /这里是具体的关于在文件系统中定义Bean定义信息的实现 /通过构造一个FileSystemResource来得到一个在文件系统中定义的Bean定义信息 /这个getResourceByPath是在BeanDefinitionReader的loadBeanDefintion中被调用的。 protected Resource g
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Spring IOC容器实现分析 IOC 容器 实现 分析

链接地址:https://www.31ppt.com/p-3166060.html