springmvc从入门到源码分析专题2_tomcat服务启动过

2020-12-24  本文已影响0人  wulin_challenge

返回专题目录

springmvc从入门到源码分析专题2_tomcat服务启动过程中如何加载ContextLoaderListener的

前言

在上一篇文章中我们做了相关前期准备,并且搭建好了我们的项目环境,成功运行了我们第一个springmvc项目helloword,但是我们并没有对我们的配置文件中的配置进行详解和分析,本篇文章及后面的文章我们将分析讲解这些配置的作用,并深入到源码讲解这些配置是如何实现的

ServletContext的作用

ServletContextListener 的作用

ServletContextListener 是 ServletContext 的监听者,用于接收有关ServletContext生命周期更改的通知事件的接口。监听 ServletContext 发生变化,如服务器启动时 ServletContext 被创建,服务器关闭时 ServletContext 要被销毁。

ContextLoaderListener 的源码解析

<!-- 使用ContextLoaderListener配置时,需要告诉它Spring配置文件的位置 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!-- 
         配置上下文载入器,上下文载入器载入除DispatherServlet载入的配置文件之外的其他上下文配置文件
      最常用的上下文载入器是一个Servlet监听器,器名称为ContextLoaderListener
     -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    private ContextLoader contextLoader;
    ...
    /**
     * Initialize the root web application context.
     */
    public void contextInitialized(ServletContextEvent event) {
        this.contextLoader = createContextLoader();
        if (this.contextLoader == null) {
            this.contextLoader = this;
        }
        this.contextLoader.initWebApplicationContext(event.getServletContext());
    }

    protected ContextLoader createContextLoader() {
        return null;
    }
    ...
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
        throw new IllegalStateException(
                "Cannot initialize context because there is already a root application context present - " +
                "check whether you have multiple ContextLoader* definitions in your web.xml!");
    }
    ...
    try {
        // Store context in local instance variable, to guarantee that
        // it is available on ServletContext shutdown.
        if (this.context == null) {
            this.context = createWebApplicationContext(servletContext);
        }
        ...
        // 配置并刷新WebApplicationContext
        ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
        configureAndRefreshWebApplicationContext(cwac, servletContext);
        ...
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
        ...
        return this.context;
    }catch (RuntimeException ex) {
    ...
}
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
    //获取 org.springframework.web.context.support.XmlWebApplicationContext 的class
    Class<?> contextClass = determineContextClass(sc);
    ...
    //通过反射创建WebApplicationContext对象
    return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
    ...
    //将ServletContext对象保存到上下文中
    wac.setServletContext(sc);
    //获取web.xml中配置的contextConfigLocation的值
    String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
    if (configLocationParam != null) {
        wac.setConfigLocation(configLocationParam);
    }
    ....
    // 刷新WebApplicationContext上下文
    wac.refresh();
}

总结

通过上面分析我们不难看出org.springframework.web.context.ContextLoaderListener的作用就是为了加载我们在web.xml中通过contextConfigLocation指定的spring bean配置文件,创建根WebApplicationContext上下文,好了,本篇文章就到这里了,下一篇我们将分析容器启动过程中org.springframework.web.servlet.DispatcherServlet是如何被执行的

返回专题目录

上一篇 下一篇

猜你喜欢

热点阅读