Tomcat工作原理解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat工作原理解析相关的知识,希望对你有一定的参考价值。

参考技术A 本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解。主要有三大部分:

1.Tomcat的简介和启动过程

2.Tomcat部署webapp

3.Tomcat处理一个http请求的过程

【简介】

Tomcat依赖/conf/server.xml这个配置文件启动server(一个Tomcat实例,核心就是启动容器Catalina)。

Tomcat部署Webapp时,依赖context.xml和web.xml(/conf/目录下的context.xml和web.xml在部署任何webapp时都会启动,他们定义一些默认行为,而具体每个webapp的  META-INF/context.xml  和  WEB-INF/web.xml  则定义了每个webapp特定的行为 )两个配置文件部署web应用。

第一部分、Tomcat的简介和启动过程

一个标准TOMCAT结构目录如上图所示:

BIN目录主要存放各种平台下启动和关闭Tomcat的脚本文件.其中 有个档是catalina.bat,打开这个windos配置文件,在非注释行加入JDK路径,例如 : SET  JAVA_HOME=C:\j2sdk1.4.2_06 保存后,就配置好tomcat环境了. startup.bat是windows下启动tomcat的文件,shutdown.bat是关闭tomcat的文件.

conf: 存放不同的配置文件(如:server.xml和web.xml); 

server.xml文件:该文件用于配置和server相关的信息,比如tomcat启动的端口号、配置host主机、配置Context 

web.xml文件:部署描述文件,这个web.xml中描述了一些默认的servlet,部署每个webapp时,都会调用这个文件,配置该web应用的默认servlet。

tomcat-users.xml文件:配置tomcat的用户密码与权限。

context.xml:定义web应用的默认行为。

/lib:存放Tomcat运行需要的库文件(JARS); 

/logs: 存放Tomcat执行时的LOG文件; 

/temp:   临时目录

/webapps:Tomcat的主要Web发布目录(包括应用程序示例); 

/work:存放jsp编译成Servlet后产生的class文件;

二、Tomcat启动过程 

1、开启Tomcat:可以在IDE中启动Tomcat的服务器,也可以手动在 /bin/目录下找到startup.bat并双击,然后程序就会依次执行以下步骤:

(1)引导(Bootstrap)启动: 调用了org.apache.catalina.startup.Bootstrap.class中的main方法,开始启动Tomcat容器;main方法如下:

publicstaticvoid main(String args[])

        if(daemon ==null)

            daemon =newBootstrap();//创建了一个引导对象try//引导对象初始化,即创建了Catalina容器                daemon.init();

            catch (Throwable t)

                t.printStackTrace();

                return;

           

       

        // 根据不同的命令参数执行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();

            elseif(command.equals("stopd"))

                args[args.length - 1] = "stop";

                daemon.stop();

            elseif(command.equals("start"))

                daemon.setAwait(true);

                daemon.load(args);

                daemon.start();

            elseif(command.equals("stop"))

                daemon.stopServer(args);

            else

                log.warn("Bootstrap: command \"" + command + "\" does not exist.");

           

        catch (Throwable t)

            t.printStackTrace();

       

    publicvoid init() 

        throws Exception 

     

        // Set Catalina path 

        // 设置catalina_home属性,tomcat启动脚本里有通过-Dcatalina.home设置          setCatalinaHome(); 

        // 设置catalina_base属性,运行多实例的时候该目录与catalina_home不同          setCatalinaBase(); 

        // 初始化classloader,读取conf/catalina.properties,根据指定的repository创建classloader 

        // 有三个classloader  分别是common、catalina、shared,tomcat6中三个相同          initClassLoaders(); 

        // 设置当前线程的classloader          Thread.currentThread().setContextClassLoader(catalinaLoader); 

        // 待研究          SecurityClassLoad.securityClassLoad(catalinaLoader); 

        // 以下通过反射调用Catalina中的方法 

        // Load our startup class and call its process() method  if (log.isDebugEnabled()) 

            log.debug("Loading startup class"); 

        Class startupClass = 

            catalinaLoader.loadClass 

            ("org.apache.catalina.startup.Catalina"); 

        Object startupInstance = startupClass.newInstance(); 

        // Set the shared extensions class loader  if (log.isDebugEnabled()) 

            log.debug("Setting startup class properties"); 

        String methodName = "setParentClassLoader"; 

        Class paramTypes[] =newClass[1]; 

        paramTypes[0] = Class.forName("java.lang.ClassLoader"); 

        Object paramValues[] =newObject[1]; 

        paramValues[0] = sharedLoader; 

        Method method = 

            startupInstance.getClass().getMethod(methodName, paramTypes); 

        method.invoke(startupInstance, paramValues); 

        catalinaDaemon = startupInstance; 

   

2)调用Bootstrap中的init(),创建了Catalina对象(核心容器):主要进行了以下三步:

//设置tomcat实例的环境变量

① Set up the environment variables required by this Tomcat instance

//实例化将用于运行Tomcat实例的通用类加载

② Instantiate the general class loaders that will be used for our running  Tomcat instance

//初始化tomcat实例

③ Initialize this Tomcat instance

(3)调用Bootstrap中的load():实际上是通过反射调用了catalina的load方法。

①Parse the main configuration file for a Tomcat instance, server.xml, converting each configuration element into the appropriate Tomcat component1。 (找到config file(server.xml);然后创建digester,解析server.xml,生成各组件对象(Server、Service、Container、Connector等)以及建立相互之间的关系。 )

(4)Start up our outermost Top Level Element—the Server instance。(最后start(),同样是在Bootstrap中通过反射调用catalina对象的start方法。 接着启动server.start()方法: ((Lifecycle) getServer()).start(); 接着调用service.start()方法。接下来是一系列的container的start,后续在分析(会部署所有的项目)

三、server.xml配置简介:  下面讲述这个文件中的基本配置信息,更具体的配置信息请参考tomcat的文档

第九章 Servllet工作原理解析

9.1 从Servlet容器说起

 

     Servlet容器:Jetty, Tomcat等。

 

  这里以Tomcat为例,  真正管理Servlet的容器是Context容器,一个Context对应一个WEB工程,

 

  9..1.1 Servlet容器的启动过程

  

  9.1.2 Web应用的初始化工作

9.2 创建Servlet实例

  9..2.1 创建Servlet实例

  9.2.2 初始化Servlet

9.3 Servlet体系结构

9.4 Servlet如何工作

9.5 Servlet中的Listener

9.6 Filter如何工作

9.7 Servlet中的URL-Pattern

9.8 总结

以上是关于Tomcat工作原理解析的主要内容,如果未能解决你的问题,请参考以下文章

Jetty的工作原理解析以及与Tomcat的比较

第九章 Servllet工作原理解析

TomcatServlet 工作原理解析

MySQL语法执行工作原理

Spring MVC工作原理及源码解析DispatcherServlet实现原理及源码解析

Java Web 深入分析 Servlet工作原理解析