首先回归一下web.xml的常用配置,看一个示例:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationcontext-*.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/springmvc-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

了解web.xml的作用之前必须要了解web容器(也称为是servlet容器)这个概念,常用的web容器有Tomcat、Jetty、JBoss等。

使用web容器,就不得不清楚什么是ServletContext。ServletContext中的信息都是由容器提供的,在web容器启动时,它作为为公共环境容器存放公共信息,为各个Servlet提供信息,也可以作为各个Servlet之间通信的桥梁。

将应用部署到web容器中,启动web容器后,web容器会读取web.xml中的配置信息,对ServletContext进行信息补充。(注:配置加载顺序为:context-param -> listener -> filter -> servlet)

好了,回到本文主题。

ContextLoaderListener

web.xml中的配置文件中ContextLoaderListener作为监听器,会监听web容器相关事件,在web容器启动或者关闭时触发执行响应程序。具体地,ContextLoaderListener继承ContextLoader类并实现了ServletContextListener接口。

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
public ContextLoaderListener() {
} public ContextLoaderListener(WebApplicationContext context) {
super(context);
} public void contextInitialized(ServletContextEvent event) {
this.initWebApplicationContext(event.getServletContext());
} public void contextDestroyed(ServletContextEvent event) {
this.closeWebApplicationContext(event.getServletContext());
ContextCleanupListener.cleanupAttributes(event.getServletContext());
}
}

  

1.关于监听

ServletContextListener接口中只有初始化和销毁的两个方法::

public interface ServletContextListener extends EventListener {
/**
** Notification that the web application initialization
** process is starting.
** All ServletContextListeners are notified of context
** initialization before any filter or servlet in the web
** application is initialized.
*/
public void contextInitialized ( ServletContextEvent sce ); /**
** Notification that the servlet context is about to be shut down.
** All servlets and filters have been destroy()ed before any
** ServletContextListeners are notified of context
** destruction.
*/
public void contextDestroyed ( ServletContextEvent sce );
}

也就是监听ServletContext的状态,ServletContext属于容器对象,在用于在容器开启或关闭时触发事件,执行contextInitialized/contextDestroyed 。如果想了解程序执行原由可以先了解事件监听设计模式。查阅Tomcat源码,tomcat触发ServletContext初始化监听事件的源码如下:

...(部分略)

Object instances[] = getApplicationLifecycleListeners();
for (int i = 0; i < instances.length; i++) {
if (!(instances[i] instanceof ServletContextListener))
continue;
ServletContextListener listener = (ServletContextListener) instances[i];
try {
if (noPluggabilityListeners.contains(listener)) {
listener.contextInitialized(tldEvent);
} else {
listener.contextInitialized(event);
}
} catch (Throwable t) {
}
} ...(部分略)

也就是,遍历所有ServletContextListener,调用监听方法。

2.关于功能

关于功能主要看initWebApplicationContext()方法。 ContextLoader中的initWebApplicationContext()方法中会创建WebApplicationContext上下文对象,并将这个对象设置到servletContext中:

ContextLoaderListener加载过程:

2.1 创建IOC容器

initWebApplicationContext调用createWebApplicationContext方法;

-->createWebApplicationContext 调用determineContextClass方法

--> defaultStrategies中加载配置文件:

defaultStrategies.getProperty(WebApplicationContext.class.getName())

ContextLoader 类中有段静态代码:

static {
try {
ClassPathResource resource = new ClassPathResource(
"ContextLoader.properties", ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException ex) {
throw new IllegalStateException(
"Could not load 'ContextLoader.properties': "
+ ex.getMessage());
} currentContextPerThread = new ConcurrentHashMap(1);
}

ContextLoader.properties 文件内容如下:

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

可知,默认加载的WebApplicationContext是XmlWebApplicationContext

题外话,如果你不想使用默认的,在web.xml中配置contextClass即可

protected Class<?> determineContextClass(ServletContext servletContext) {
String contextClassName = servletContext.getInitParameter("contextClass");
if(contextClassName != null) {
try {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
...(略)

也就是这种形式:

<context-param>
<param-name>contextClass</param-name>
<param-value>webApplicationContext类全路径名称</param-value>
<context-param>

org.springframework.web.context.support包下查询webApplicationContext。

2.1 IOC容器配置加载,初始化

这一步主要是调用configureAndRefreshWebApplicationContext,可知在上一步中创建了WebApplicationContext对象(ConfigurableApplicationContext类型),也就是创建了IOC容器对象,接着就要给这个对象进行配置参数的设置了。

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
String configLocationParam;
if(ObjectUtils.identityToString(wac).equals(wac.getId())) {
configLocationParam = sc.getInitParameter("contextId");
if(configLocationParam != null) {
wac.setId(configLocationParam);
} else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
}
} wac.setServletContext(sc);
configLocationParam = sc.getInitParameter("contextConfigLocation");
if(configLocationParam != null) {
wac.setConfigLocation(configLocationParam);
} ConfigurableEnvironment env = wac.getEnvironment();
if(env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources(sc, (ServletConfig)null);
} this.customizeContext(sc, wac);
wac.refresh();
}

可知,首先会给WebApplicationContext对象设置ServletContext全局信息,然后读取><param-name>contextConfigLocation</param-name>对应的.xml中的配置信息,例如:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationcontext-*.xml</param-value>
</context-param>

这些applicationcontext-*.xml配置文件中的信息之后再执行ConfigurableApplicationContext.refresh()方法就会被加载到IOC容器中。

IOC容器的初始化过程,参考下一篇文章。

springmvc web.xml配置之 -- ContextLoaderListener的更多相关文章

  1. springmvc web.xml配置之 -- SpringMVC IOC容器初始化

    SpringMVC IOC容器初始化 首先强调一下SpringMVC IOC容器初始化有些特别,在SpringMVC中除了生成一个全局的spring Ioc容器外,还会为DispatcherServl ...

  2. SpringMvc web.xml配置详情

    出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...

  3. springmvc web.xml配置之 -- DispatcherServlet

    springMVC servlet配置与启动 看一下springmvc的web.xml常见配置: <servlet> <!-- 配置DispatcherServlet --> ...

  4. Spring 及 SpringMVC的web.xml配置详解

    出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...

  5. Spring MVC的web.xml配置详解(转)

    出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...

  6. Spring mvc的web.xml配置详解

    1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在web.xml配置监听器ContextLoaderListener(l ...

  7. Java web.xml 配置技巧—动态欢迎页地址

    我们的 Java   Web  项目在配置web.xml 欢迎页地址默认是index.html .index.jsp ,不知道有人注意过没有,如果我要配置成/index/user.action  或者 ...

  8. 1、Spring MVC的web.xml配置详解(转)

    版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilt ...

  9. springmvc 项目完整示例07 设置配置整合springmvc springmvc所需jar包springmvc web.xml文件配置

    前面主要是后台代码,spring以及mybatis的整合 下面主要是springmvc用来处理请求转发,展现层的处理 之前所有做到的,完成了后台,业务层和持久层的开发完成了 接下来就是展现层了 有很多 ...

随机推荐

  1. New Concept English Two 4

    听力口语是一起的,其中,受中国英语发音的影响,我们的听力识别度会很差,歪果仁发的地道英语,极有可能我们听不懂.这涉及到:自然拼读法的训练,还有纠音练习.当然,听简单的美剧的音频,然后练习是最好的. 新 ...

  2. Android Studio利用GitHub托管项目

    自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onL ...

  3. springboot整合mybatis增删改查(三):mybatis逆向工程

    上一篇已经把项目基本框架完善,接下来就是利用Mybatis Generator逆向工程进行mybatis的整合. 我们在创建项目开始的时候已经勾选web,mybatis,sql等,但是这些依赖还是不够 ...

  4. .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型

    .NET 中提供了很多判断某个类型或实例是某个类的子类或某个接口的实现类的方法,然而这事情一旦牵扯到泛型就没那么省心了. 本文将提供判断泛型接口实现或泛型类型子类的方法. 本文内容 .NET 中没有自 ...

  5. android如何改变应用程序安装后显示的图标

    修改 res目录下所有ic_launcher.png 为你想显示的图标

  6. 《DSP using MATLAB》Problem 3.3

    按照题目的意思需要利用DTFT的性质,得到序列的DTFT结果(公式表示),本人数学功底太差,就不写了,直接用 书中的方法计算并画图. 代码: %% -------------------------- ...

  7. RabbitMQ引入

    引入MQ话题 可能很多人有疑惑:MQ到底是什么?哪些场景下要使用MQ? 前段时间安装了RabbitMQ,现在就记录下自己的学习心得吧.首先看段程序: class Program { static vo ...

  8. Web Server部署架构图

    一.整体架构图 二.框架的瓶颈 上述框架的瓶颈在存储NFS,现在较多的使用的是GFS分布式存储

  9. Spring cloud 之Feign基本使用

    首先导入feign的依赖: <!-- 添加feign声明式webservice client --> <dependence> <groupId>org.sprin ...

  10. HDU 1710 Binary Tree Traversals(树的建立,前序中序后序)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...