WebApplicationContext
WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便Web应用环境可以访问Spring应用上下文。Spring专门为此提供了一个工具类ServletContextUtils,通过该类的getWebApplicationonContext(ServletContext sc) 方法,可以从ServletContext中获取WebApplicationContext实例。
在非Web停用环境下,Bean只有singleton 和 prototype两种作用域,WebApplicationContext为Bean添加了三个新的作用域:request、session和global session。
WebApplicationContext的类体系结构
下面看一下WebApplicationContext的类继承体系:
由于Web应用比一般的应用拥有更多的特性,因此WebApplication扩展了Application。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容器的上下应用文就可以实现互访,二者实现了融合。如下图所示:
ConfigurableWebApplicationContext扩展了WebApplicationContext,它允许通过配置的方式实例化WebApplicationContext,同时定义了两个重要的方法。
- setServletContext(ServletContext ServletContext):为Spring设置Web应用上下文,以便二者整合。
- SetConfigLocations(String[] configLocations):设置Spring配置文件地址,一般情况下,配置文件地址是相对于Web根目录的地址,如/WEB-INF/smart-dao.xml、/WEB-INF/smart-service.xml等。但用户也可以使用带资源类型前缀的地址,如:classpath:com/smart/beans.xml等。
WebApplicationContext初始化
WebApplicationContext的初始化方式和BeanFactory、ApplicationContext有所区别,因为WebApplicationContext需要ServletContext实例,也就是说,它必须在拥有Web容器的前提下才能完成启动工作。有过Web开发经验的人都知道,可以在web.xml中配置自启动的servlet或定义web容器监听器(ServletContextListener),借助二者中的任何一个,就可以完成启动Spring Web应用上下文的工作。
Spring分别提供了用于启动WebApplicationContext的Servlet和Web容器监听器:
- org.springframework.web.context.ContextLoaderServlet
- org.springframework.web.context.ContextLoaderListener
二者的内部都实现了启动WebApplicationContext实例的逻辑,只要根据Web容器的具体情况选择二者之一,并在web.xml中完成我配置既可。
下面使用ContextLoaderListener启动WebApplicationContext的具体配置
<!-- ①指定配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/smart-dao.cml,/WEB-INF/smart-service.xml
</param-value>
</context-param>
<!-- ②声明web容器监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener通过Web容器上下文参数contextConfigLocation获取Spring配置文件的位置。用户可以指定多个配置文件,用逗号、空格或冒号分隔均可。对于未带资源类型前缀的配置文件路径,WebApplicationContext默认这些路径相对于Web的部署根路径。当然,也可以采用带资源类型前缀的路径配置,如“class*:/smart-*.xml”和上面的配置是等效的。
如果在不支持容器监听器的低版本Web容器中,则可以采用ContextLoaderServlet完成相同的工作,代码如下所示。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/smart-dao.cml,/WEB-INF/smart-service.xml
</param-value>
</context-param>
<!-- ①声明自启动的Servlet-->
<servlet>
<servlet-name>springContextLoaderServlet</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<!-- ②启动顺序-->
<load-on-startup>
1
</load-on-startup>
</servlet>