《Spring--IoC和DI》中把Spring比作了一个婚姻介绍所,准确的说应该是把IoC容器比作了婚姻介绍所,那么,这里就给他起个完整的名字叫IoC婚姻介绍所吧,这篇重点来看看这个IoC婚姻介绍所到底是怎么回事?各位都知道每家公司都会有BOSS这个角色,他一般是这个公司的实际代表者;而Spring中BeanFactory就是这家IoC婚姻介绍所的大BOSS,IoC容器的实际代表者,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
BeanFactory虽是大老板,但什么事情都不是他能亲历亲为的,想要这个婚姻介绍所发展壮大还需引进专业性人才,各司其职才是正道。因此,在BeanFactory的基础上衍生出了很多接口和实现类,这里的接口你就暂时先理解为那些趾高气昂的部门经理吧,至于实现类就是那些苦逼的普通员工了(顿时想到了苦逼的程序猿)。LZ大概数了下,这家IoC婚姻介绍所部门经理有十人,普通员工有十九人。鉴于管理层和员工比例失调,就先谈谈优秀的普通员工代表吧,这十九位普通员工中,有一位特别能干活,特别能吃苦,并且获得八一劳动奖章的员工,他叫XmlBeanFactory,没错,就是他,就是在十九人中事情最多的一位,该员工主要职责是:以XML方式描述组成应用的对象以及对象间的依赖关系,XmlBeanFactory类将获取此XML配置元数据,并用他来构建一个完全可配置的系统或应用。下图为这哥们的工作状态:
当然,能描述组成应用的对象以及对象间的依赖关系不止是Xml,还是有很多方式的,比如Annotation-based,这里就不做过多的介绍了,因为道理的想通的,用到的话查询下相关技术文档即可。
一个公司总有一些人是来干活的,一些人是打酱油的,这在管理层和普通员工中都会存在,下面就来看看优秀的部门经理代表,他叫ApplicationContext,是Context包的核心接口,我们可以采用声明式和编程式两种方式使用ApplicationContext。他除了拥有BeanFactory的所有功能外,还支持MessageSource,国际化消息访问;资源访问,如URL和文件;事件传播,实现了ApplicationListener接口的bean;载入多个(有继承关系)上下文,使得每个上下文都专注于特定的层次,比如应用的web层。其实说了半天也没有触及到它的核心职责,下面就来介绍核心职责:在ApplicationContext接口的众多实现类中,有3个是我们经常用到的:
1.ClassPathXmlApplicationContext:从类路径ClassPath中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。
2.FileSystemXmlApplicationContext:从指定的文件系统路径中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。
3.XmlWebApplicationContext:从Web应用中的寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。
ApplicationContext实例化后,同样通过getBean方法从ApplicationContext容器中获取装配好的Bean实例以供使用。与BeanFactory不同的是,ApplicationContext容器实例化后会自动对所有的单实例Bean进行实例化与依赖关系的装配,使之处于待用状态。而BeanFactory容器实例化后并不会自动实例化Bean,只有当Bean被使用时BeanFactory容器才会对该Bean进行实例化与依赖关系的装配。
在Java项目中通过ClassPathXmlApplicationContext类手动实例化ApplicationContext容器通常是不二之选。但对于Web项目就不行了,Web项目的启动是由相应的Web服务器负责的,因此,在Web项目中ApplicationContext容器的实例化工作最好交给Web服务器来完成。
Spring为此提供了两种解决方案,一种是基于ContextLoaderListener实现的(此方案只适用于Servlet2.4及以上规范的Servlet容器)。例如,在web.xml中加入如下代码:
contextConfigLocation
classpath:spring-config/applicationContext.xml
org.springframework.web.context.ContextLoaderListener
另外一种方案则是基于ContextLoaderServlet实现的。例如,在web.xml中加入如下代码:
contextConfigLocation
classpath:spring-config/applicationContext.xml
context
org.springframework.web.context.ContextLoaderServlet
1
从servlet容器启动时加载组件的顺序来看,Listener组件是优先于Servlet组件的。基于Servlet方式的加载方案主要是为了兼容Servlet2.3及以下规范的Servlet容器。以Tomcat为例,Tomcat5.x都已经支持Servlet2.4规范了,因此,基于Listener方式启动Spring容器是目前的主流选择。
最后再说一点,关于BeanFactory和ApplicationContext的选择,一般,除非你有更好的理由,否则尽量使用ApplicationContext,就好像,既然该公司有了这么多部门经理,别什么事都找大老板,有什么事找什么人最好。
对了,再说一点,既然IoC婚姻介绍所有了员工,那客户必不可少,最少也得需要一位客户来撑门面,也就是说至少要配置一个