ApplicationContext介绍

本文深入介绍了Spring框架中的ApplicationContext,探讨了其与BeanFactory的关系及不同之处。解释了ApplicationContext的主要实现类,包括ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,并讨论了如何初始化这些类。此外,文章还详细说明了WebApplicationContext的特性和配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的身躯了。ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。

ApplicationContext类体系结构

ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件


和BeanFactory初始化相似,ApplicationContext的初始化也很简单,如果配置文件放置在类路径下,用户可以优先使用ClassPathXmlApplicationContext实现类:

ApplicationContext ctx = new ClassPathXmlApplicationContext("com/baobaotao/context/beans.xml")

对于ClassPathXmlApplicationContext来说,"com/baobaotao/context/beans.xml"等同于"classpath: com/baobaotao/context/beans.xml"。

如果配置文件放置在文件系统的路径下,则可以优先考虑使用FilySystemXmlApplicationContext实现类: 

ApplicationContext ctx =new FileSystemXmlApplicationContext("com/baobaotao/context/beans.xml");  

对于FileSystemXmlApplicationContext来说,“com/baobaotao/context/beans.xml”等同于“file:com/baobaotao/context/beans.xml”。

         还可以指定一组配置文件,Spring会自动将多个配置文件在内存中"整合"成一个配置文件,如下所示:

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"conf/beans1.xml","conf/beans2.xml"});

当然FileSystemXmlApplicationContext和ClassPathXmlApplicationContext都可以显式使用带资源类型(classpath:或file:)前缀的路径,它们的区别在于如果不显式指定资源类型前缀,将分别将路径解析为文件系统路径和类路径罢了。

在获取ApplicationContext实例后,就可以像BeanFactory一样调用getBean(beanName)返回Bean了。ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有"第一次惩罚"的问题。

WebApplicationContext类体系结构

WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便Web应用环境可以访问Spring应用上下文。Spring专门为此提供一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc)方法,即可以从ServletContext中获取WebApplicationContext实例。


由于Web应用比一般的应用拥有更多的特性,因此WebApplicationContext扩展了ApplicationContext。WebApplicationContext定义了一个常量ROOT_WEB_APPLICATION_ CONTEXT_ATTRIBUTE,在上下文启动时,WebApplicationContext实例即以此为键放置在ServletContext的属性列表中,因此我们可以直接通过以下语句从Web容器中获取WebApplicationContext:

WebApplicationContext wac = (WebApplicationContext)servletContext.getAttribute(

WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

这正是我们前面所提到的WebApplicationContextUtils工具类getWebApplicationContext (ServletContext sc)方法的内部实现方式。这样Spring的Web应用上下文和Web容器的上下文就可以实现互访,二者实现了融合(图3-10):

 
图3-10  Spring和Web应用的上下文融合

WebApplicationContext初始化

WebApplicationContext的初始化方式和BeanFactory、ApplicationContext有所区别,因为WebApplicationContext需要ServletContext实例,也就是说它必须在拥有Web容器的前提下才能完成启动的工作。有过Web开发经验的读者都知道可以在web.xml中配置自启动的Servlet或定义Web容器监听器(ServletContextListener),借助这两者中的任何一个,我们就可以完成启动Spring Web应用上下文的工作。

所有版本的Web容器都可以定义自启动的Servlet,但只有Servlet 2.3及以上版本的Web容器才支持Web容器监听器。有些即使支持Servlet 2.3 的Web服务器,但也不能在Servlet初始化之前启动Web监听器,如Weblogic 8.1、WebSphere 5.x、Oracle OC4J 9.0。

Spring分别提供了用于启动WebApplicationContext的Servlet和Web容器监听器:

org.springframework.web.context.ContextLoaderServlet;

org.springframework.web.context.ContextLoaderListener。

两者的内部都实现了启动WebApplicationContext实例的逻辑,我们只要根据Web容器的具体情况选择两者之一,并在web.xml中完成配置就可以了。

下面是使用ContextLoaderListener启动WebApplicationContext的具体配置:

代码清单3-22  通过Web容器监听器引导

 
  1. …  
  2. <!--①指定配置文件--> 
  3. <context-param>                                                        
  4.      <param-name>contextConfigLocation</param-name>   
  5.      <param-value> 
  6.        /WEB-INF/baobaotao-dao.xml, /WEB-INF/baobaotao-service.xml  
  7.    </param-value> 
  8. </context-param> 
  9. <!--②声明Web容器监听器--> 
  10. <listener>   
  11.      <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> 
  12. </listener> 

ContextLoaderListener通过Web容器上下文参数contextConfigLocation获取Spring配置文件的位置。用户可以指定多个配置文件,用逗号、空格或冒号分隔均可。对于未带资源类型前缀的配置文件路径,WebApplicationContext默认这些路径相对于Web的部署根路径。当然,我们可以采用带资源类型前缀的路径配置,如"classpath*:/baobaotao-*.xml"和上面的配置是等效的。

如果在不支持容器监听器的低版本Web容器中,我们可采用ContextLoaderServlet完成相同的工作:

代码清单3-23  通过自启动的Servlet引导

 
  1. …  
  2. <context-param> 
  3.      <param-name>contextConfigLocation</param-name>   
  4.      <param-value>/WEB-INF/baobaotao-dao.xml, /WEB-INF/baobaotao-service.xml </param-value> 
  5. </context-param> 
  6. …  
  7. <!--①声明自动启动的Servlet --> 
  8. <servlet>   
  9.     <servlet-name>springContextLoaderServlet</servlet-name> 
  10.     <servlet-class>org.springframework.web.context.ContextLoaderServlet </servlet-class> 
  11.     <!--②启动顺序--> 
  12.     <load-on-startup>1</load-on-startup> 
  13. </servlet> 

由于WebApplicationContext需要使用日志功能,用户可以将Log4J的配置文件放置到类路径WEB-INF/classes下,这时Log4J引擎即可顺利启动。如果Log4J配置文件放置在其他位置,用户还必须在web.xml指定Log4J配置文件位置。Spring为启用Log4J引擎提供了两个类似于启动WebApplicationContext的实现类:Log4jConfigServlet和Log4jConfigListener,不管采用哪种方式都必须保证能够在装载Spring配置文件前先装载Log4J配置信息。

代码清单3-24  指定Log4J配置文件时启动Spring Web应用上下文

 
  1. <context-param> 
  2.         <param-name>contextConfigLocation</param-name> 
  3.         <param-value> 
  4.            /WEB-INF/baobaotao-dao.xml,/WEB-INF/baobaotao-service.xml  
  5.         </param-value> 
  6.     </context-param> 
  7.      <!--①指定Log4J配置文件位置--> 
  8.     <context-param>                                             
  9.         <param-name>log4jConfigLocation</param-name> 
  10.         <param-value>/WEB-INF/log4j.properties</param-value> 
  11.     </context-param> 
  12.  
  13.     <!--②装载Log4J配置文件的自启动Servlet --> 
  14.     <servlet> 
  15.         <servlet-name>log4jConfigServlet</servlet-name> 
  16.         <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class> 
  17.         <load-on-startup>1</load-on-startup> 
  18.     </servlet> 
  19.     <servlet> 
  20.         <servlet-name> springContextLoaderServlet</servlet-name> 
  21.         <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> 
  22.     <load-on-startup>2</load-on-startup> 
  23. </servlet> 

注意上面我们将log4jConfigServlet的启动顺序号设置为1,而springContextLoaderServlet的顺序号设置为2。这样,前者将先启动,完成装载Log4J配置文件初始化Log4J引擎的工作,紧接着后者再启动。如果使用Web监听器,则必须将Log4jConfigListener放置在ContextLoaderListener的前面。采用以上的配置方式Spring将自动使用XmlWebApplicationContext启动Spring容器,即通过XML文件为Spring容器提供Bean的配置信息。



### Spring ApplicationContext 的声明及初始化方法 `ApplicationContext` 是 Spring 框架中的核心接口之一,用于加载配置文件并管理 Bean 容器。以下是几种常见的 `ApplicationContext` 声明和初始化方式: #### 1. 使用 XML 配置文件的方式 当使用基于 XML 的配置时,可以通过以下两种常见实现类来创建 `ApplicationContext` 实例。 - **ClassPathXmlApplicationContext** 如果配置文件位于类路径下,则可以使用此实现类。 ```java ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ``` - **FileSystemXmlApplicationContext** 当配置文件位于文件系统中而非类路径下时,可以选择该实现类。 ```java ApplicationContext context = new FileSystemXmlApplicationContext("/path/to/applicationContext.xml"); ``` 上述两种方式均会触发容器的初始化过程[^3],包括读取配置文件、注册 BeanDefinition 和完成依赖注入等操作。 --- #### 2. 使用 Java Config 方式 随着 Spring 提供了更灵活的 Java 配置支持,越来越多开发者倾向于采用纯 Java 注解的方式来替代传统的 XML 文件。 - 创建一个带有 `@Configuration` 注解的类,并在其内部定义各种 Bean 方法。 - 使用 `AnnotationConfigApplicationContext` 来加载此类作为配置源。 ```java @Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } } // 加载配置类 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); ``` 这种方式完全摆脱了对外部 XML 文件的依赖,使得代码更加简洁易维护[^4]。 --- #### 3. Web 应用场景下的自动装配 对于典型的 Spring MVC 或者其他类型的 Web 应用程序来说,通常不需要手动显式地创建 `ApplicationContext` 对象。而是由 Servlet 容器负责调用 `FrameworkServlet#initWebApplication()` 方法,在其中执行如下逻辑链路: 1. 调用 `createWebApplicationContext(parent)` 方法实例化一个新的 `XmlWebApplicationContext`; 2. 设置基本属性(如 Environment、Parent Context 等); 3. 执行最终的刷新动作即 `refresh()` 方法以完成整个上下文环境准备阶段的工作流程[^2]。 这种机制极大地简化了开发人员的操作负担,同时也保证了一致性和可靠性。 --- #### 总结 无论是在简单命令行工具还是复杂的分布式微服务架构当中,合理选用合适的 `ApplicationContext` 类型及其对应的初始化策略都是非常重要的环节。以上介绍了三种主要途径——基于 XML 的传统模式、现代化全注解驱动设计思路以及针对特定领域优化过的自动化解决方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值