内容简介:进入tomcat官网:https://tomcat.apache.org/ 下载对应版本的源码
No.1 搭建环境
1.1、下载tomcat源码
进入tomcat官网:https://tomcat.apache.org/ 下载对应版本的源码
1.2、导入Eclipse
- 新建一个 Java 项目
- 将Tomcat源码包中的java目录下的文件拷贝到src目录
- 导入外部依赖包
ant.jar ecj-4.4.jar jaxrpc.jar wsdl4j-1.5.2.jar
No.2 Tomcat顶层结构
上图大概展示了tomcat的结构,主要包括如下几个模块:
- Server:
服务器的意思,代表整个tomcat服务器,一个tomcat只有一个Server;
- Service:
Server中的一个逻辑功能层,一个Server可以包含多个Service;
- Connector:
称作连接器,是Service的核心组件之一,一个Service可以有多个Connector,主要是连接客户端请求;
- Container:
Service的另一个核心组件,按照层级有Engine,Host,Context,Wrapper四种,一个Service只有一个Engine,其主要作用是执行业务逻辑;
- Jasper:
JSP引擎;
- Session:
会话管理;
No.3 Server
Server是Tomcat最顶层的容器,代表着整个服务器,即一个Tomcat只有一个Server,Server中包含至少一个Service组件,用于提供具体服务。
这个在配置文件中也得到很好的体现(port=”8005” shutdown=”SHUTDOWN”是在8005端口监听到”SHUTDOWN”命令,服务器就会停止)。
tomcat中定义了一个Server接口,其声明如下:
public interface Server extends Lifecycle {
它继承了Lifecycle接口,这样当调用start()和stop()方法时,所有已定义的Services也会启动或停止。
- 它的标准实现是:org.apache.catalina.core.StandardServer 类。
- Server元素表示整个Catalina servlet容器。
- 它的属性代表整个servlet容器的特征。
- 服务器可能包含一个或多个服务,以及顶级命名资源集。
- 它的具体实现应该在其构造函数中使用ServerFactory类注册(singleton)实例。
No.4 Service
前面我们讲过,一个Server至少包含一个Service组件来提供具体的服务。
那Service的基本功能大致是接收客户端的请求,然后解析请求,完成相应的业务逻辑,然后把处理后的结果返回给客户端。
一般会提供两个节本方法,一个start打开服务Socket连接,监听服务端口,一个stop停止服务释放网络资源。
tomcat中定义一个Service接口,其声明如下:
public interface Service extends Lifecycle {
- 一个Service是一组包含一个或多个Connectors,这些Connectors共享一个Container来处理请求。
- Connector负责处理请求监听,Container负责处理请求处理
- 从conf/server.xml文件的配置可以知道,Service相当于Connector和Engine组件的包装器,将一个或者多个Connector和一个Engine建立关联关系。在默认的配置文件中,定义了一个叫Catalina 的服务,它将HTTP/1.1和AJP/1.3这两个Connector与一个名为Catalina 的Engine关联起来。
一个Server可以包含多个Service(它们相互独立,只是公用一个JVM及类库),一个Service负责维护多个Connector和一个Container。
No.5 Connector
Connector是连接器,用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。
server.xml默认配置了两个Connector:
- 监听端口8080,这个端口值可以修改,connectionTimeout定义了连接超时时间,单位是毫秒,redirectPort 定义了ssl的重定向接口,根据上述配置,Connector会将ssl请求转发到8443端口。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
- 监听端口8009,AJP表示Apache Jserv Protocol,它将处理Tomcat和Apache http服务器之间的交互,此连接器用于处理我们将Tomcat和Apache http服务器结合使用的情况,如在同一台物理Server上部署一个Apache http服务器和多台Tomcat服务器,通过Apache服务器来处理静态资源以及负载均衡时,针对不同的Tomcat实例需要AJP监听不同的端口。
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
Connector在tomcat中的设计大致如下:
- Connector使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型
- ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter
Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的
Processor用于将Endpoint接收到的Socket封装成Request,Processor用来实现HTTP协议的
Adapter充当适配器,用于将Request转换为ServletRequest交给Container进行具体的处理
No.6 Container
Container 用于封装和管理 Servlet,以及具体处理 Request 请求,在Container内部包含了4个子容器,4个子容器的作用分别是:
- Engine:
引擎,用来管理多个站点,一个Service最多只能有一个Engine;
- Host:
代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
- Context:
代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
- Wrapper:
每一Wrapper封装着一个Servlet;
No.7 tomcat启动流程
tomcat的启动流程很标准化,入口是BootStrap,统一按照生命周期管理接口Lifecycle的定义进行启动。
首先,调用init()方法逐级初始化,接着调用start()方法进行启动,同时,每次调用伴随着生命周期状态变更事件的触发。
- org.apache.catalina.startup.Bootstrap的程序入口main方法,具体实现如下:
public static void main(String args[]) { if (daemon == null) { // Don't set daemon until init() has completed Bootstrap bootstrap = new Bootstrap(); try { bootstrap.init(); } catch (Throwable t) { handleThrowable(t); t.printStackTrace(); return; } daemon = bootstrap; } else { // When running as a service the call to stop will be on a new // thread so make sure the correct class loader is used to prevent // a range of class not found exceptions. Thread.currentThread().setContextClassLoader(daemon.catalinaLoader); } try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; } if (command.equals("startd")) { args[args.length - 1] = "start"; daemon.load(args); daemon.start(); } else if (command.equals("stopd")) { args[args.length - 1] = "stop"; daemon.stop(); } else if (command.equals("start")) { daemon.setAwait(true); daemon.load(args); daemon.start(); } else if (command.equals("stop")) { daemon.stopServer(args); } else if (command.equals("configtest")) { daemon.load(args); if (null==daemon.getServer()) { System.exit(1); } System.exit(0); } else { log.warn("Bootstrap: command \"" + command + "\" does not exist."); } } catch (Throwable t) { // Unwrap the Exception for clearer error reporting if (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } handleThrowable(t); t.printStackTrace(); System.exit(1); } }
- org.apache.catalina.startup.Bootstrap的初始化方法,具体实现如下:
public void init() throws Exception { // 1、设置catalina.home的配置:将catalina.home系统属性设置为当前工作目录(如果尚未设置)。 setCatalinaHome(); // 2、设置catalina.base的配置:如果没有设置的话,将当前的工作目录为了catalina.base的设置 setCatalinaBase(); // 3、初始化类加载器:commonLoader、catalinaLoader、sharedLoader initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); // 加载我们的启动类并调用其process()方法 if (log.isDebugEnabled()) log.debug("Loading startup class"); //4、加载启动类 Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina"); //5、实例化启动类 Object startupInstance = startupClass.newInstance(); if (log.isDebugEnabled()) log.debug("Setting startup class properties"); //6、设置方法参数 String methodName = "setParentClassLoader"; Class<?> paramTypes[] = new Class[1]; paramTypes[0] = Class.forName("java.lang.ClassLoader"); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); // 7、调用启动类的setParentClassLoader方法设置共享扩展类加载器 method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; }
- org.apache.catalina.startup.Bootstrap的start()方法,具体实现如下:
/** * Start the Catalina daemon. */ public void start() throws Exception { // 如果启动类为实例化,则调用init()方法 if( catalinaDaemon==null ) init(); //获取启动类的start方法 Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null); //调用启动类的start方法,即调用org.apache.catalina.startup.Catalina的start()方法 method.invoke(catalinaDaemon, (Object [])null); }
具体时序图如下:
总结
整个Tomcat从代码的角度来看,就是这样的:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 各种Java应用服务器对比
- 服务器设计方案之应用限流
- 无服务器架构的发展与应用
- Web服务器、应用程序服务器、HTTP服务器区别
- OTP-19.3 发布,Erlang 应用服务器
- OTP 19.2 发布,Erlang 应用服务器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ajax修炼之道
(美)哥特兰、高伯瑞斯、艾米亚 / 徐锋,胡冰 / 电子工业出版社 / 2006-4 / 29.8
Ajax将静态Web页面转变为充满交互的应用。现在您不需要牺牲Web应用程序部署的简单性,就可以将“胖”客户端应用程序部署到客户端。不过对于很多人业说,Ajax看起来很难。这就是我们撰写本书的原因。作为实践的指导,本书揭开了Ajax神秘的面纱,教您如何以简单的方式使用Ajax。本书内容覆盖了DHTML、Javascript和闻名已久的XmlHttp Request回调技术的基础知识。您将了解如何将......一起来看看 《Ajax修炼之道》 这本书的介绍吧!