源码解读(一): spring在web容器中的初始化过程

Spring容器本质上就是创建类的工厂,并且对类进行管理。

1. Spring 在web容器中通常是通过在web.xml文件中配置切入点来进行相关初始化的。

web.xml中加载Spring容器的相关配置

当web容器解析web.xml文件时,会初始化ContextLoaderListener类,这个类继承了ServletContextListener,也就是Web容器监听器。并且实现了ServletContextListener接口中的contextInitialized和contextDestroyed方法。

源码解读(一): spring在web容器中的初始化过程_第1张图片

其中 contextInitialized 是在容器初始化上下文的时候调用的,contextDestroyed是容器销毁上下文的时候调用的。
2. 初始化 ContextLoaderListener类

首先我们整体看一下ContextLoaderListener类中所有的属性和方法:

源码解读(一): spring在web容器中的初始化过程_第2张图片

由上图可以看到,ContextLoaderListener不仅继承了ContextLoader,并且还拥有私有属性 ContextLoader对象,而ContextLoader类是用来执行根应用程序上下文的实际初始化工作。

  • 下面,我们粗略的看一下ContextLoader所有的属性和方法。

    源码解读(一): spring在web容器中的初始化过程_第3张图片

  • 从图中可以看出,首先要执行的是static初始化方法。

    源码解读(一): spring在web容器中的初始化过程_第4张图片

  • static方法的主要作用是用来获取默认策略的值。在spring-web-3.2.9.RELEASE.jar包中,默认策略的值放在ContextLoader.properties文件中。

    源码解读(一): spring在web容器中的初始化过程_第5张图片

  • 我们可以从下图看出,指定了WebApplicationContext的实例化对象为XmlWebApplicationContext类。
    contextLoader.properties

  • ContextLoader初始化过程中,会通过xml中contextConfigLocation的配置,获取Spring相关的xml文件所在路径,所以一般在web.xml中,还需要配置如下配置(举例,实际value值根据项目的配置进行填写):

    源码解读(一): spring在web容器中的初始化过程_第6张图片

接下来,回到ContextLoaderListener方法中,首先执行的便是contextInitialized方法。其中ServletContextEvent 对象是通过web容器传递过来的,主要调用contextLoader类中的initWebApplicationContext方法。initWebApplicationContext方法的主要作用是“使用在构造时所提供的应用程序上下文,初始化给定servlet上下文的Spring Web应用程序”。

源码解读(一): spring在web容器中的初始化过程_第7张图片

  • 下面我们一步步分析initWebApplicationContext类到底做了什么。

    1. 确定在初始化上下文中只存在一个ContextLoader* 相关的配置,否则抛出异常。
      1

    2. 打印相关日志,并且计算开始时间。
      源码解读(一): spring在web容器中的初始化过程_第8张图片

    3. 在本地实例变量中存储上下文,保证它在ServletContext关闭时可用。其中createWebApplicationContext方法的作用是 “实例化该加载器的根WebApplicationContext,如果指定了默认上下文类或自定义上下文类”。默认上下文即 xmlWebApplicationContext。
      3

    4. 判断应用上下文是否是属于ConfigurableWebApplicationContext实例。默认的xmlWebApplicationContext是属于ConfigurableWebApplicationContext实例的。如果应用上下文没有生效,需要确认应用上下文是否设置了父上下文。loadParentContext方法主要功能是“具有默认实现(可能被子类覆盖)的模板方法,以加载或获取将用作根WebApplicationContext的父上下文的ApplicationContext实例。” configureAndRefreshWebApplicationContext的主要作用就是“获取web.xml中配置的contextConfigLocation路径,获取应用的访问路径,获取spring相关的XML配置文件的路径,并且刷新当前的WebApplicationContext配置相关。” 最后将该上下文对象放入servlet上下文参数中。
      源码解读(一): spring在web容器中的初始化过程_第9张图片

    5. 获取当前线程的类加载器, 如果ContextLoader的类加载器和当前线程的类加载器一样,则应用上下文对象赋值给currentContext。
      源码解读(一): spring在web容器中的初始化过程_第10张图片

至此为止,contextLoaderListener的contextInitialized方法执行完成。在这个方法里面我们初始化了ServletContext的实例对象,并且获得了spring配置相关的xml文件。


引申知识点:
context root 是什么?
答: context root指的是当web引用在WEB容器中运行时,唯一识别该项目的根路径。例如 现在A应用路径为/config ,另一个B应用路径为/config/test。对于web请求来说,它们决定了将哪些URL请求转发到哪些应用。如果请求路径为/config/abcds的请求都会被转发到A应用,路径为/config/test/abcds的请求就会被转发到B应用。
这个关系同样适用于被称为root context / 的context root . 当应用被指定为root context, 它将会响应没有被明确context root处理的所有请求。

下一篇,继续源码解读。

你可能感兴趣的:(spring,java,知识积累)