Java Web 启动流程

请求在浏览器#

域名 ---> 查找 DNS 浏览器缓存, 计算机缓存, hosts, DNS 服务器, DNS 备用服务器

​ ---> 根据 DNS 找到 ip

---> ip, port 建立 TCP 连接

---> CDN 请求静态资源

---> 负载均衡(分布式) ---> 容器(服务器)

​ ---> 后面的 url → 选择服务器的子容器处理用户请求

如果是 https 请求,还要验证 SSL 证书

三次握手,四次分手...流程,为什么.

网络不是这里提的重点,具体查看计算机网络的三次握手四次分手

请求到了服务端#

请求 ---> 浏览器 ---> 实体服务器 ---> HTTP 服务器 ---> Web 容器 ---> Servlet

tomcat 的准备工作#

Tomcat 主要提供 Web 容器主要功能,不是 HTTP 服务器的功能.

Tomcat 附带的 HTTP 服务器功能太过简单,仅仅是给开发者提供便利而已...

Servlet 等级 :

1. Tomcat
    2. Container 容器
    3. Engine
    4. Host
    5. Servlet 容器
    6. Context   --->   直接管理 Wrapper, 真正管理 Servlet 的容器是 Context
    7. Wrapper   --->   Servlet 在容器中的包装类

一个 Web 应用对应一个 Context 容器

容器的配置属性由应用的 web.xml 指定 ---> web.xml 的作用

在请求来之前,容器首先会做一些工作...

---> 添加一个 Web 应用

---> 会创建一个 StandardContext 容器,并设置参数

有哪些重要参数?

  1. url ---> tomcat 中访问路径
  2. path ---> 实际的物理路径
  3. ContextConfig ---> 负责整个 Web 应用配置的解析工作

---> 把 Context 容器添加到父容器 Host 中

---> 调用 tomcat 的 start 方法

上面的过程还可以细化,Context 的 init 细节之类的...

---> Web 应用初始化

--- ContextConfig 中的 configureStart() 实现

主要解析 web.xml ---> web.xml 有啥? Web 应用的入口,servlet 的配置...Web 应用的关键信息

web.xml 属性被解析到 Context 中

解析后,Servlet 生成实例...

---> 如果 load-on-startup 配置大于 0,Context 容器初始化时实例化

​ 创建 Servlet 实例,从 Wrapper 的 loadServlet() 开始

​ 获取 servletClass → 交给 InstanceManager → 创建一个基于 servletClass.class 的对象

​ 如果 servlet 配置了 jsp-file,则这就是 JspServlet

---> Servlet 初始化

StandardWrapper 的 inintServlet() 调用 servlet 的ninit()

把包装了 standardWrapper 的 standardWrapper Facede 作为 ServletConfig 传给 Servlet

若 servlet 关联 Jsp,则 JspServlet 模拟一次简单请求调用 Jsp,编译 Jsp 文件为类,初始化类...

Servlet 是单例多线程

web.xml 多次声明,实现多个实例...

容器层 (如 tomcat)#

---> Web 服务器接收到 HTTP 请求

---> 创建 org.apache.coyote.Request(封装了 HTTP 请求) ,org.apache.coyote.Response

---> 交给用户线程,封装为 org.apache.catalina.connector.Request, org.apache.catalina.connector.Response

---> 贯穿整个 Servlet 容器,直到交给 Servlet.RequestFacade, ResponseFacaed

---> ServletRequest, ServletResponse 交给 Servlet

---> Serlvet 处理 HttpServletRequest, HttpServletResponse

到达 servlet 之前#

根据请求路径后面的 url 来确定到底哪个 servlet

---> 定义在 web.xml 中

---> tomcat7 有一个 mapper 类,保存了 Container 容器中所有的子容器的信息,org.apache.catalina.connector.Request 在进入Container 容器前,Mapper 将会根据这次请求的 hostname 和 contextpath 将 host 和 context 容器设置到 Request 的mappingData 属性中...

所以当 Request 进入 Container 容器之前,对于它要访问哪个子容器就确定了.

Mapper 怎么会有容器的完整关系?

MapperListener 的 init() ...

请求还可能经过一个 Filter ...

<filter>

<filter-mapping>

拦截...

到达 servlet#

web.xml 判断对应 Servlet 是否存在,不在 404

在 检查是否实例化

若容器不存在所需 Servlet,检索 Servlet,并将其加载到容器的地址空间中,产生 Servlet 实例...

容器调用 servlet init() 对 servlet 进行初始化(只会在 servlet 第一次载入时调用)

doGet(),doPost()

实际调用 service() 处理 HTTP 请求

---> JVM 为每个请求分配独立的线程+

其它#

HTTP 请求的本质是 Socket 通信

TCP/IP 应用层,传输层,网络层,网络接口层

​ HTTP TCP 路由,寻址 物理...

基于 HTTP 的服务器,Tomcat, nginx

Servlet 没有 main() 方法,如何执行.

​ 是在 容器 (如 tomcat) 控制下执行的

以线程的方式处理

Servlet 接口

​ GenericServlet

​ HttpServlet

Servlet 生命周期由容器控制

​ init()

​ service()

​ destory()

Jsp -----> Servlet 的扩展

forward -------> 服务器内部重定向 url 不变

redirect --------> 客户端重定向 url 变 ​效率低于前者,重新发送请求

ajax ---> js -- XmlHttpRequest

​ 异步请求数据