Apache Tomcat 学习(由浅入深)

今天,我们一起学习一下Tomcat,本文内容主要参考与 Apache Tomcat 7 官方文档,以及Tomcat 7源码。内容主要分为一下五个方面:

一、什么是Tomcat?

Apache Tomcat 是一个Java Servlet、JavaServer Pages、Java Expression Language 和Java WebSocket技术的开源实现。

二、Tomcat安装和配置

1、下载Tomcat 7安装包,进入 Apache Tomcat 7 下载页面,选择适合你系统的版本,这里下载的是window版本。

2、下载成功后,解压。这里解压到了D:\Tomcat\apache-tomcat-7目录底下。

3、配置JAVA_HOME,在系统环境变量中新建JAVA_HOME环境变量并指定为系统JDK的安装目录。JAVA_HOME环境变量配置

4、点击\bin目录底下的startup.bat 可以看到Tomcat成功运行。

5、编写Servlet简单demo

1)、在\webapps 目录下创建HelloWeb目录,进入该目录,创建\classes和\lib目录,并新建web.xml文件。

2)、打开IDEA,创建maven工程,引入Servlet依赖:

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

 3)、构建HelloServlet类:

public class HelloServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.println("Hello World");
        writer.close();
    }
}

4)、在maven工具点击package,打包项目,并将生成的\target\classes拷贝到\HelloWeb\classes目录底下,将javax.servlet-api-3.1.0.jar拷贝到\HelloWeb\lib目录底下

5)、配置web.xml文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

6)、重新启动Tomcat 可以看到浏览器输出Hello World.

三、Tomcat的目录结构

Tomcat 目录

1、\bin 里面含有启动tomcat所有要的jar包和脚本文件。

bootstrap.jar、commons-daemon.jar、tomcat-juli.jar这三个包是tomcat在启动时加载的类,其中,bootstrap.jar含有tomcat启动类,在catalina.bat启动脚本文件中, 我们可以看到如下脚本:

%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%

其中

%_EXECJAVA%代表JAVA命令

 %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" 代表JAVA 命令运行时的JVM参数和系统变量

-classpath 代表指定JAVA文件的路径

"%CLASSPATH%"代表D:\Tomcat\apache-tomcat-7\apache-tomcat-7.0.103\bin\bootstrap.jar.

rem Add on extra jar file to CLASSPATH
rem Note that there are no quotes as we do not want to introduce random
rem quotes into the CLASSPATH
if "%CLASSPATH%" == "" goto emptyClasspath
set "CLASSPATH=%CLASSPATH%;"
:emptyClasspath
set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"

 %MAINCLASS%代表在"%CLASSPATH%"路径下的类,这里是

set MAINCLASS=org.apache.catalina.startup.Bootstrap

%CMD_LINE_ARGS%代表main函数的入参

%ACTION%代表最后一个入参,也就是Tomcat运行的动作,org.apache.catalina.startup.Bootstrap类会根据最后一个参数决定Tomcat的状态.下图是org.apache.catalina.startup.Bootstrap#main()方法

Main

Tomcat的启动脚本简化来看是这样的:

java org.apache.catalina.startup.Bootstrap start

2、\conf包含Tomcat Web服务的配置文件,其中最重要的是server.xml文件:

<?xml version='1.0' encoding='utf-8'?>
<!-- 每一个Tomcat服务只有一个Server port是指TCP/IP端口,用于接收shutdown命令 shutdown是指shutdown命令的String值-->
<Server port="8005" shutdown="SHUTDOWN">
  <!-- 代表Server的JNDI资源 所有的web项目都可以访问到 -->
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- tomcat 服务 包含 一个Engine 和 至少一个 Connector -->
  <Service name="Catalina">
    <!-- 连接器 它确保Tomcat可以作为一个独立的web服务 主要包含ProtocolHandler 和 Adapter ProtocolHandler又包含EndPoint和Processor EndPoint主要用于接受请求 Processor 主要用于处理请求 Adapter 主要用于将处理过的请求交给具体的servlet处理 -->
    <!-- port 连接器监听的端口号 -->
    <!-- protocol 连接器使用的传输协议 -->
    <!-- connectionTimeout 连接建立后 等待请求的时间 否则超时 单位是微秒 -1代表不设置超时时间-->
    <!-- redirectPort 假如该连接器不支持SSL请求 那么它会将请求转发到该端口的连接器 -->
    <!-- acceptCount 可接收的请求数目 超过该值 请求将阻塞 -->
    <!-- maxThreads 连接器可以创造的用于处理请求的最大线程数目 -->
    <!-- minSpareThreads 最小空闲处理请求的线程数目 -->
    <!-- URIEncoding 用于解码URI字节的字符编码 -->
    <Connector port="8080" 
               protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               acceptCount="100"
               maxThreads="200"
               minSpareThreads="10"
               URIEncoding="ISO-8859-1" />
    <!-- 引擎,用来管理多个站点,一个Service最多只能有一个Engine -->
    <!-- name 引擎的名字 -->
    <!-- localhost 默认Host 必须 用于处理没有匹配的请求 -->
    <Engine name="Catalina" defaultHost="localhost">
      <!-- 代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点 -->
      <!-- name 站点名称 跟站点域名对应 -->
      <!-- appBase 应用的基础路径 默认是webapps -->
      <!-- unpackWARs 是否自动解压war包 -->
      <!-- autoDeploy 是否开启自动部署 -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
           <!-- 代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件 -->
           <!-- path 请求的路径 -->
           <!-- docBase 应用的存放路径 HelloWeb -->
           <Context path="HelloWeb"  docBase="HelloWeb">
           </Context >
      </Host>
    </Engine>
  </Service>
</Server>

3、\lib目录主要存放tomcat的依赖类.

4、\webapps应用存放Servlet应用.

四、Tomcat的整体架构。

我们先通过一张图来整体的了解一下Tomcat。

Architecture

我们来解释一下各个部分,Tomcat的核心部件主要是Connector和Container。

Connector:主要负责接受外部的网络链接,并将请求交给Container处理,主要组件由Connector,ProtocalHandler,EndPoint,Handler,Adapter。

Container:主要负责管理Servlet,处理业务逻辑。主要组件由Engine,Host,Context,Wrapper。

此外,Tomcat还提供了JMX(Java Management Extensions,即Java管理扩展)管理和监控Tomcat组件,日志服务,JNDI和SESSION管理等。

下面对途中各个名词做简单介绍:

组件实现类父组件是否是容器说明
ServerStandardServer每个Tomcat服务只有一个Server,负责管理Tomcat服务和Service的生命周期。
ServiceStandardServiceServer可以看作一个完整的对外服务,主要由Connector和Engine组成并负责管理他们的生命周期。Connector负责处理外部请求,Engine负责处理业务逻辑。
EngineStandardEngineService是一种Container,主要负责管理Host的生命周期。
HostStandardHostEngine是一种Container,主要负责管理Context的生命周期。
ContextStandardContextHost是一种Container,主要负责管理wrapper的生命周期。
Wrapper(Servlet)StandardWrapperContext是一种Container,主要负责管理Servlet的生命周期。
ConnectorConnectorService一个Service可以由一个或多个Connector组成,主要负责监听外部请求,并将请求转发到Engine。
ProtocalHandlerHttp11NioProtocol(还有其他实现这是最常用的)Connector主要由EndPoint和Handler组成,负责处理请求,并将请求交给Adapter处理。
EndPointNioEndpoint(还有其他实现这是最常用的)ProtocalHandler创建守护进程监听端口请求。解析请求并将请求交给Handler处理。
HandlerConnectionHandlerProtocalHandler建立ProtocalHandler和Adapter之间的连接,并将请求转发发到Adapter上。
AdapterCoyoteAdapterConnector将请求转换成ServletRequest,ServletResponse,并根据请求的路径解析对应的Host、Context、Wrapper。并将ServletRequest,ServletResponse交给Engine处理。

 

 

 

 

 

 

5、Tomcat的类加载机制:

在java程序中,java虚拟机规范推荐采用父子委托的类加载机制,即子类先请求父类加载器加载,加载不到则使用子类加载器加载。但tomcat的类加载过程打破了这一机制。我们先来看一下tomcat涉及哪些类加载器。

Bootstrap:负责加载java运行时类和Ext包下的类。

Common:以应用类加载器为父类,是tomcat顶层的公用类加载器,其路径由conf/catalina.properties中的common.loader指定,默认指向${catalina.base}/lib;${catalina.home}/lib下的包。

Catalina:以Common类加载器为父类,是用于加载Tomcat应用服务器的类加载器,其路径由server.loader指定,默认为空,此时tomcat使用Common类加载器加载应用服务器。

Shared:以Common类加载器为父类,是用于加载Tomcat应用服务器的类加载器,其路径由shared.loader指定,默认为空,此时tomcat使用Common类加载器加载应用服务器。

WebappX:以 Shared类加载器为父类,是用于加载Tomcat应用的类加载器。

Web应用类加载器默认的加载顺序是:

(1).先从缓存中加载;
(2).如果没有,则从JVM的Bootstrap类加载器加载;
(3).如果没有,则从当前类加载器加载(按照WEB-INF/classes、WEB-INF/lib的顺序);
(4).如果没有,则从父类加载器加载,由于父类加载器采用默认的委派模式,所以加载顺序是AppClassLoader、Common、Shared。

tomcat提供了delegate属性用于控制是否启用java委派模式,默认false(不启用),当设置为true时,tomcat将使用java的默认委派模式,这时加载顺序如下:

(1).先从缓存中加载;
(2).如果没有,则从JVM的Bootstrap类加载器加载;
(3).如果没有,则从父类加载器加载,加载顺序是AppClassLoader、Common、Shared。
(4).如果没有,则从当前类加载器加载(按照WEB-INF/classes、WEB-INF/lib的顺序);

6、tomcat的初始化过程:

Init

7、请求过程:

Parse

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值