springmvc web.xml配置之ContextLoaderListener

首先回归一下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进行信息补充。

好了,回到本文主题。

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()方法,ContextLoaderListener继承ContextLoader,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容器的初始化过程,参考下一篇文章。

原文地址:https://www.cnblogs.com/chenjunjie12321/p/9357534.html

时间: 2024-10-11 17:39:03

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

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

SpringMVC IOC容器初始化 首先强调一下SpringMVC IOC容器初始化有些特别,在SpringMVC中除了生成一个全局的spring Ioc容器外,还会为DispatcherServlet生成一个容器,具体的下一篇有讲述. 我们知道spring中单纯使用main函数就可以生成一个容器,如下: public class MainTest { public static void main(String[] args){ ApplicationContext appContext =

springmvc web.xml配置之 -- DispatcherServlet

springMVC servlet配置与启动 看一下springmvc的web.xml常见配置: <servlet> <!-- 配置DispatcherServlet --> <servlet-name>springMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定s

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

出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在web.xml配置监听器ContextLoaderListener(listener-class) ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在web.

Java web.xml 配置技巧—动态欢迎页地址--欺骗tomcat

我们的Java Web项目在配置web.xml 欢迎页地址默认是index.html .index.jsp ,不知道有人注意过没有,如果我要配置成/index/user.action  或者 /userList.do 什么的怎么办呢?你可能觉得直接配置就OK了,我告诉你不行.如果可以,你可以忽略本方法.下面讲讲如果不能配置动态地址,怎么办. 配置如下: <welcome-file-list> <welcome-file>/user/index.shtml</welcome-f

maven工程web层的web.xml配置文档内容

下面是web层,web.xml配置文档里面需要配置的东西: 1.lo4j配置 2.读取spring文件配置 3.设计路径变量值 4.spring字符集过滤器 5.登陆过滤器 6.springMVC核心配置 7.session过期时间 8.错误页面跳转 以下是实例: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSch

Web.XML 配置学习

web.xml的作用(参考资料):https://www.cnblogs.com/yqskj/articles/2233061.html 每个javaEE工程中都有web.xml文件,那么它的作用是什么呢?它是每个web.xml工程都必须的吗? 一个web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的. web.xml文件是用来初始化配置信息:比如Welcome页面.servlet.servlet-mapping.filter.listener.启动加载级别等.

web.xml 配置applicationContext.xml

web.xml中classpath:和classpath*:  有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 有时候会用模糊匹配的方式配置多配置文件. 但是如果配置文件是在jar包里,模糊匹配就找不到了.可以用逗号隔开的方式配置多个配置文件. 如: <listener>  <listener-class>org.springframework.web.conte

基于注解的Spring MVC(所需jar包,web.xml配置,Spring文件配置,@Controller,@RequestMapping,@RequestParam,model填參,EL取值)

1.加入jar 2.web.xml配置: <?xml version="1.0" encoding="UTF-8"? > <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocati

SSH框架 web.xml配置

<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.s