Java Web 启动加载顺序简述

普通的 Java App 的程序入口就是 main 方法,但对于 Java Web App 是没有这个 main 方法的,或者说接触不到这个 main 方法。Java Web App 的启动,依赖于实现了 Java Servlet Container 的应用服务器,如 Apache Tomcat、Jetty 等。

Servlet Container

通常应用服务器在启动时,会根据配置文件中的路径寻找对应的 Web App。以 Apache Tomcat 为例,Tomcat 中最顶层的容器是 Server,代表着整个应用服务器。其中一个 Server 可以启动至少一个 Service 用以提供服务。而一个 Service 中,主要包含了 Connector 和 Container。顾名思义,Connector 即是监听端口,提供连接,而 Container 就是应用的容器。一个 Container 可以包含多个 Host(虚拟主机,站点),每个 Host 又包含多个 Context(Web App 对应 App 内的 web.xml),每个 Context 下又包含多个 Wrapper,其中封装着 Servlet。

通常我们能更多接触到的就是从 Connector 和 Container 之后的部分,只要查看 server.xml 配置文件,就可以很清晰的看到层级关系。

而我们的 Web App 的启动就从 Context 加载 web.xml 开始。

Web.xml

web.xml 是 Java Servlet 规范根据 XML 模式来定义的部署描述符文件。

web.xml 文件提供有关包含 Web App 的 Web 组件的配置和部署信息。

web.xml 文件必须位于 Web App 所在的目录层次结构上下文下的 WEB-INF 目录。

一个 Web App 中,web.xml 并不是必须的。假如 Web App 中,不需要 web.xml 中的信息,那么 web.xml 是可以被忽律的。

web.xml 中有多种标签,具体支持多少种,建议查看官方文档,就我们常用的来说,它的加载顺序为:ServletContext -> Context-param -> Listener -> Filter -> Servlet(同类多个节点以出现顺序依次加载)

启动顺序

大致启动顺序流程如下:

  1. 应用服务器启动时,创建 Container
  2. 设置 Container 的基本属性,设置 Host /webapps
  3. Container 创建一个 ServletContext,应用于整个项目 /webapps/ROOT -> http://localhost:80
  4. Container 先从 web.xml 读取 context-param 和 listener 这两种标签元素
  5. 读取 context-param 转化为键值对并存入 ServletContext
  6. 读取 listener 创建监听,如 ContextLoaderListener
  7. 读取 Filter 创建拦截器,如 CharacterEncodingFilter
  8. 读取 Servlet 创建 Servlet,如 Spring DispatcherServlet

参考资料