码迷,mamicode.com
首页 > 编程语言 > 详细

[Java]Servlet工作原理之一:Servlet的容器

时间:2017-10-09 12:08:39      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:java   name   发布   配置文件   start   适应   bsp   sources   extc   

Servlet 不能够独立运行,需要在它的容器中运行,容器管理着它创建到销毁的整个过程。在看 Servlet 之前,我们先看下 Servlet 的我们最熟悉的一个容器——Tomcat。

一、Tomcat 体系结构

技术分享

Tomcat 有两个重要组件:连接器(Connector)和容器(Engine容器及其子容器),我们结合 server.xml 配置文件来看一下这两个组件。

1 连接器(Connector)

首先向 Tomcat 发送的请求可以分为两类:

  • Tomcat 作为应用服务器:请求来自前端的 Web 服务器,如 Nginx、Apache、IIS 等。
  • Tomcat 作为独立服务器:请求来自浏览器。

这些不同的请求需要不同的连接器来接收,在 Service 中有一个引擎和多个连接器,以适应不同情况。常见的连接器有四种:HTTP连接器、SSL连接器、AJP连接器、proxy连接器。在定义连接器时可以配置的属性有很多,连接器公用属性如下:

  • className 指定实现 Connector 接口的类
  • enableLookups 是否通过request.getRemoteHost()获取客户端的主机名,默认true
  • redirectPort 如果连接器的协议是HTTP,当收到HTTPS请求时,转发到此端口

HttpConnector 的属性:

  • className 指定实现 Connector 接口的类
  • port 监听端口,默认8080
  • address 指定监听地址,默认为所有地址
  • bufferSize 设置由端口创建的输入流缓存大小,默认2048byte
  • protocol 连接器使用的协议,默认HTTP/1.1
  • maxThreads 支持的最大并发连接数,默认200
  • connectionTimeout 等待客户端发送请求的超时时间,默认60000,即1分钟
  • acceptCount 设置等待队列的最大长度,默认为10。当tomcat所有处理线程均繁忙时,新链接被放置于等待队列中

JkConnector 的属性:

  • className 指定实现 Connector 接口的类
  • port 设定AJP端口号
  • protocol 必须为 AJP/1.3

2 容器(Engine容器及其子容器)

在 Tomcat 中有 Engine、Host、Context 及 Wrapper 四种容器,它们的包含关系如下图所示

技术分享

上述的包含并不是继承关系,而是当子容器创建好后会放入到父容器中。Servlet 被包装成 Wrapper,然后真正管理 Servlet 的是 Context 容器,一个 Context 对应一个 Web 应用。

  • Wrapper 封装了具体访问的资源,即 Servlet;
  • Context 封装了各个 Wrapper 资源的集合;
  • Host 封装了 Context 资源的集合;
  • Engine 可以看成是对 Host 的逻辑封装。

我们再来看一下它们的继承关系,这些容器的接口都继承自 Container 接口,为什么要按层次分别封装一个对象呢?为了方便统一管理,在不同层次的配置其作用域是不一样的。

技术分享

2.1 Engine

Engine 下面拥有多个 Host,即虚拟主机,它的责任就是将用户的请求分配给一个虚拟主机处理。为什么要使用虚拟主机呢?当我们有两个应用时,如下图的 Love 应用和 SDJTU 应用。我们想访问“倪培.我爱你”域名时直接达到 Love 应用,访问“www.sdjtu.net.cn”域名时直接到达 SDJTU 应用,但是如果不设置虚拟主机是无法在一个 Tomcat中做到的。那么,我们可以设置两个虚拟主机,并指定请求到达这个虚拟主机后要去访问的目录。

技术分享

在 Engine 标签中有几个属性可以填写

  • name 定义 Engine 的名字
  • className 指定实现 Engine 接口的类,默认是 StandardEngine
  • defaultHost 指定处理请求的默认主机

在 Engine 标签里还可以包含以下几个元素

  • Logger
  • Realm
  • Valve
  • Host

2.2 Host

Host 代表一个虚拟主机,在它下面有多个 Context,一个 Context 代表一个 Web 应用。

技术分享

在 Host 标签中的几个属性

  • name 定义 Host 的名字
  • className 指定实现 Host 接口的类,默认是 StandardHost
  • appBase 指定虚拟主机的目录,默认是 webapps
  • unpackWARs 是否先展开war文件再运行。如果为 false 将直接运行 war 文件
  • autoDeploy 表示是否支持热部署
  • alias 用来指定主机别名
  • deployOnStartup 是否在启动时自动发布目录下的所有Web应用

在 Host 标签中还可以包含以下几个元素

  • Logger 
  • Realm
  • Valve
  • Host

2.3 Context

Context 代表运行在虚拟主机上的单个 Web 应用。

技术分享

在 Context 标签中的几个属性

  • className 指定现实 Context 接口的类,默认是 StandardContext 类
  • path 配置Web应用对应的URL,即跟在域名后面的内容
  • docBase 指定要执行的Web应用
  • reloadable 当项目下的 class 文件被更新时,是否重新加载Web应用
  • cookies 指定是否通过 Cookies 来支持 Session,默认为 true
  • useNaming 指定是否支持 JNDI,默认值为 ture

在 Context 标签中的元素

  • Logger
  • Realm
  • Resource
  • ResourceParams

 

2 Tomcat 启动过程

Tomcat 从 7.0 开始增加了一个启动类 org.apache.catalina.startup.Tomcat。通过这个类的实例调用 start() 方法就可以启动 Tomcat,还可以通过这个对象增加和修改 Tomcat 的配置参数,来动态的添加 Context、Servlet 等。

当 Context 容器初始化状态为 init 时,添加到 Context 容器的 Listener 将会被调用。ContextConfig 继承了 LifecycleListener 接口,它是在调用了 Tomcat.addWebapp 时被加入到 StandardContext 容器的,这个类将会负责整个 Web 应用的配置解析工作。ContextConfig 的 init 方法将会主要完成以下工作:

  1. 创建 ContextDigester 对象来解析 XML 配置文件
  2. 读取默认的 context.xml 配置文件,如果存在则解析它
  3. 读取默认的 Host 配置文件,如果存在则解析它
  4. 读取默认的 Context 自身的配置文件,如果存在则解析它
  5. 设置 Context 的 DocBase

当 ContextConfig 的 init 方法完成后,Context 容器会执行 startInternal 方法,主要包括以下工作

  1. 创建读取资源文件的对象
  2. 创建 ClassLoader 对象
  3. 设置应用的工作目录
  4. 启动相关的辅助类,如 logger、realm、resources 等
  5. 修改启动状态,通知感兴趣的观察者
  6. 子容器的初始化
  7. 获取 servletContext 并设置必要参数
  8. 初始化“load on startup”的 Servlet

Web 应用的初始化是在 ContextConfig 的 configureStart 方法中实现的,应用初始化主要是解析 web.xml 文件。web.xml 文件中的配置会被解析成 WebXml 对象,然后这些配置会放入 Context 中,并且 Servlet 配置会被包装成 StandardWrapper 并作为子容器添加到 Context 中。

[Java]Servlet工作原理之一:Servlet的容器

标签:java   name   发布   配置文件   start   适应   bsp   sources   extc   

原文地址:http://www.cnblogs.com/tengyunhao/p/7481324.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!