如果说BeanFactory是Spring的“心脏”,那么ApplicationContext 就是完整的“身躯”了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。
ApplicationContext的主要实现类是ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。下面了解一下 ApplicationContext的类继承体系,如图
从图可以看出,ApplicationContext 继承了HierarchicalBeanFactory 和ListableBeanFactory接口,在此基础上,还通过多个其他的接口扩展了BeanFactory 的功能。这些接口如下。
1、ApplicationEventPublisher: 让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了ApplicationListener 事件监听接口的Bean可以接收到容器事件,并对事件进行响应处理。在ApplicationContext 抽象实现类
ArtitaplicatiContet中存在一个AipioinMiacaste它负责保存所有的监听器,以便在容器产生上下文事件时通知这些事件监听者。
2、MessageSource: 为应用提供il8n国际化消息访问的功能。
3、ResourcePattermResolver: 所有ApplicationContext 实现类都实现了类似于
PathMatchingResourcePattermResolver的功能,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。
4、LifeCycle: 该接口提供了start0和stop0两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被ApplicationContext 实现及具体Bean 实现,ApplicationContext会将start/stop 的信息传递给容器中所有实现了该接口的Bean,以达到管理和控制JMX、任务调度等目的。
ConfigurableApplicationContext扩展于ApplicationContext,它新增了两个主要的方法: refresh0和 close0,让ApplicationContext具有启动、刷新和关闭应用上下文的能力。在应用上下文关闭的情况下调用refresh(即可启动应用上下文,在已经启动的状态下调用refreshO则可清除缓存并重新装载配置信息,而调用close(0则可关闭应用上下文。这些接口方法为容器的控制管理带来了便利,但作为开发者,我们并不需要过多关心这些方法。和BeanFactory初始化相似,ApplicationContext 的初始化也很简单。如果配置文件放置在类路径下,则可以优先考虑使用ClassPathXmlApplicationContext实现类。
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/matao/context/beans.xml");
对于ClassPathXmlApplicationContext来说,“com/matao/context.beans.xml”相当于“classpath:com/matao/context/beans.xml”。
如果配置文件放在了文件系统的路径下,则优先考虑使用FileSystemXmlApplicationContext实现类
ApplicationContext ctx = new FileSystemXmlApplicationContext("com/matao/context/beans.xml");
对于FileSystemXmlApplicationContext来说,“com/matao/context.beans.xml”相当于“file:com/matao/context/beans.xml”。
还可以指定一组配置文件, Spring 会自动将多个配置文件在内存中“整合”成一个配置文件,如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext (
new String[]("conf/beans1 .xml", "conf/beans2. xml");
当然,FileSystemXlApplicationContext 和lassathXmlpplicationContext都可以显式使用带资源类型前缀的路径,它们的区别在于如果不显式指定资源类型前缀,则分别将路径解析为文件系统路径和类路径。在获取ApliationContext实例后,就可以像BeanFactory一样调用getBeanbeanName)返回Bean了opplicationContext的初始化和BeanFactory有一个重大的区别: BeanFactory在初始化容器时,并未实例化Bean,直到第一 -次访问某个Bean时才实例化目标Bean;而ApplicationContxt则在初始化应用上下文时就实例化所有单实例的Bean. 因此,ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有“第一次惩罚”的问题。
Spring支持基于类注解的配置方式,主要功能来自于Spring一个叫JavaConfig的子项目。javaConfig已经升级为Spring核心框架的一部分。一个标注@Configuration注解的POJO类即可提供Spring所需的Bean的配置信息
//①表示是个配置信 息提供类@Configuration
public class Beang {
//②定义一个Bean
QBean(name = "car")
public Car buildcar() {
Car car = new Car() ;
car .setBrand ("红旗CA72");car.setMaxSpeed (200) ;
return car;
和基于XML文件的配置方式相比,类注解的配置方式可以很容易地让开发者控制Bean的初始化过程,比基于XML文件的配置方式更加灵活。
Spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplicationContext。来看-一个使用AnnotationConfigApplicationContext启动Spring容器的示例,如所示。
public class AnnotationAppl icationContextTest {
@Test
public void getBean() (
//①通过一个带Configuration的POJO装载Bean配置
ApplicationContext ctx = new AnnotationConfigApplicationContext (Beans .class) ;Car car =ctx. getBean ("car", Car.class);
assertNotNull(car) ;
AnntationConfigApplicationContext将加载Beans.class 中的Bean 定义并调用Beans.class中的方法实例化Bean,启动容器并装配Bean.