`
toking79
  • 浏览: 23228 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Tomcat源码系列1--Tomcat启动流程1

阅读更多

最近在看Tomcat的源码,下面用博客记下看源码的一些心得。

Tomcat是从org.apache.catalina.startup.Bootstrap#main()开始启动. 大致分为三个步骤,即init、load和start。代码如下: 

public static void main(String args[]) { 
        try { 
            // Attempt to load JMX class 
            new ObjectName("test:foo=bar"); 
        } catch (Throwable t) { 
            System.out.println(JMX_ERROR_MESSAGE); 
            try { 
                // Give users some time to read the message before exiting 
                Thread.sleep(5000); 
            } catch (Exception ex) { 
            } 
            return; 
        } 
        if (daemon == null) { 
            daemon = new Bootstrap(); 
            try { 
                daemon.init();   ★1 
            } catch (Throwable t) { 
                t.printStackTrace(); 
                return; 
            } 
        } 
        try { 
            String command = "start"; 
            if (args.length > 0) { 
                command = args[args.length - 1]; 
            } 
            if (command.equals("startd")) { 
                args[0] = "start"; 
                daemon.load(args); 
                daemon.start(); 
            } else if (command.equals("stopd")) { 
                args[0] = "stop"; 
                daemon.stop(); 
            } else if (command.equals("start")) { 
                daemon.setAwait(true); 
                daemon.load(args);   ★2 

             // 反射调用Catalina的start方法 
                daemon.start();        ★3 
            } else if (command.equals("stop")) { 
                daemon.stopServer(args); 
            } 
        } catch (Throwable t) { 
            t.printStackTrace(); 
        } 
    }  

  
从以上可以很清楚的看出tomcat是通过参数的不同进行相应的命令调用。
★1 启动、初始化(加载类)
启动之前要进行相应的init()初始化,进行相应的环境设置以及包的加,以下是init()方法。(org.apache.catalina.startup.Bootstrap.init())

public void init() 
        throws Exception 
    { 
        setCatalinaHome();//设置Catalina安装目录 
        setCatalinaBase();//设置Catalina工作目录 
        initClassLoaders();//加载jar包 

       // 将classload设置进线程,以便我们使用时进行调用       
        Thread.currentThread(). 
                      setContextClassLoader(catalinaLoader); 
        SecurityClassLoad.securityClassLoad(catalinaLoader); 

        // 加载启动类和调用它的process方法 
        if (log.isDebugEnabled()) 
            log.debug("Loading startup class"); 
        Class startupClass = 
            catalinaLoader.loadClass 
            ("org.apache.catalina.startup.Catalina"); 
        Object startupInstance = startupClass.newInstance(); 

        // 设置共享扩张类加载器 
        if (log.isDebugEnabled()) 
            log.debug("Setting startup class properties"); 
        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); 
        method.invoke(startupInstance, paramValues); 
        catalinaDaemon = startupInstance; 
    } 

 
在加载jar的时候,需要初始化classloader,代码如下:(org.apache.catalina.startup.Bootstrap)

private void initClassLoaders() { 
        try { 
            commonLoader = createClassLoader("common", null); 
            catalinaLoader= createClassLoader("server", commonLoader); 
            sharedLoader = createClassLoader("shared", commonLoader); 
        } catch (Throwable t) { 
            log.error("Class loader creation threw exception", t); 
            System.exit(1); 
        } 
    } 

 

tomcat中的加载方式是:
|-------commonLoader (common)-> System Loader
|-------sharedLoader (shared)-> commonLoader -> System Loader
|-------catalinaLoader(server) -> commonLoader -> System Loader

Common是公共类加载器,负责加载tomcat内部和web应用程序可以看到的类(%CATALINA_HOME%/bin/common下的jar文件),Catalina负责加载的是tomcat内部使用的类(%CATALINA_HOME%/server下的jar文件),这些类对web应用程序不可见。Shared负责加载的是web应用程序之间共享的类(%CATALINA_BASE%/shared下的jar文件),这些类对于tomcat内部是不可见的。如果%CATALINA_HOME%/conf/catalina.Properties中没有指定Common的搜索路径,则用当前的类的类加载器即系统类加载器作为Common。  

★2 装载相应的资源
下面主要讲解tomcat的load()方法。下图是Catalina.load方法的时序图。


 
(1) 从上面的时序图可以看出首先调用Catalina类的load()方法,具体代码如下:
(org.apache.catalina.startup.Catalina)。

public void load() { 
        initDirs(); 

        // Before digester - it may be needed 
        initNaming(); 

        // Create and execute our Digester 
        Digester digester = createStartDigester(); 
       
        try { 
            inputSource.setByteStream(inputStream); 
            digester.push(this); 
            digester.parse(inputSource); //对server.xml进行解析 
            inputStream.close(); 
        } 
       ...... 
        // Start the new server 
        if (server instanceof Lifecycle) { 
            try { 
                server.initialize();  //server初始化工作 
            } catch (LifecycleException e) { 
                log.error("Catalina.start", e); 
            } 
        } 
        long t2 = System.currentTimeMillis(); 
        log.info("Initialization processed in " + (t2 - t1) + " ms"); 

    } 

 
(2) 在上面的load()方法中需要进行server的初始化工作,下图为Catalina.initialize的时序图,从图中可以看出server初始化所完成的工作。


 

至此,load方法结束,初期化的工作结束,下面开始进入start方法。

★3 容器启动
容器启动时,会调用Catalina.start(),下图为它的时序图。从图中可以看出StandardService的start方法被调用后会分别对Container和Connector进行start方法的调用。



 

1. Bootstrap调用Catalina的start方法
Catalina.start()方法(org.apache.catalina.startup.Catalina.start())

    public void start() { 
        // 启动server 
        if (server instanceof Lifecycle) { 
            try { 
                ((Lifecycle) server).start(); 
                        ...... 
       } 

 
2. Catalina调用StandardServer的start方法
StandardServer.start() (org.apache.catalina.core.StandardServer.start() ) 

public void start() throws LifecycleException {       
        synchronized (services) { 
            for (int i = 0; i < services.length; i++) { 
                if (services[i] instanceof Lifecycle) 
                    ((Lifecycle) services[i]).start(); 
            }  
} 

        

3. StandardServer调用StandardService的start方法

org.apache.catalina.core.StandardService.start() ) 
        public void start() throws LifecycleException { 
                  if (container != null) { 
            synchronized (container) { 
                if (container instanceof Lifecycle) { 
              //  standardEngine的启动 
                    ((Lifecycle) container).start(); 
                } 
            } 
       //两个connector的启动,8080和8009   
       synchronized (connectors) {   
           for (int i = 0; i < connectors.length; i++) {   
               if (connectors[i] instanceof Lifecycle)   
                   ((Lifecycle) connectors[i]).start();   
                  }   
       }   
} 

 
以上StandardService.start()方法主要实现了两个功能,standardEngine的启动和connector的启动,下面分别来介绍。

 

  • 大小: 16.4 KB
  • 大小: 10.9 KB
  • 大小: 15.8 KB
1
4
分享到:
评论
1 楼 xuhang1128 2011-03-20  
学习了,看完您的文章自己再去看看能够更清晰点

相关推荐

    tomcat-redis-session-manager源码

    《深入解析Tomcat-Redis-Session-Manager源码》 在现代Web应用中,服务器端会话管理是一个至关重要的部分,特别是在高并发、分布式环境中。Tomcat作为最流行的Java Servlet容器,提供了丰富的功能来支持这一需求。...

    tomcat源码,servlet-api源码

    《深入理解Tomcat源码与Servlet-API》 Tomcat,作为Apache软件基金会的顶级项目,是Java Servlet和JavaServer Pages(JSP)的开源Web应用服务器,被广泛应用于中小型企业的Web服务部署。7.0.59版本是Tomcat的一个...

    开发工具 apache-tomcat-8.0.41-windows-x86

    开发工具 apache-tomcat-8.0.41-windows-x86开发工具 apache-tomcat-8.0.41-windows-x86开发工具 apache-tomcat-8.0.41-windows-x86开发工具 apache-tomcat-8.0.41-windows-x86开发工具 apache-tomcat-8.0.41-...

    tomcat8.5.20-redis-session共享-JAR包大全

    apache-tomcat-8.5.20.tar.gz源码包和context.xml文件,这套配置是我自己亲测可用的。。另外我用的redis4这个版本。注意:如果你使用的TOMCAT其他版本。例如tomcat6或者7这套JAR包可能不可用,tomcat8.0没有测试。...

    apache-tomcat-9.0.45-windows-x64

    apache-tomcat-9.0.45-windows-x64apache-tomcat-9.0.45-windows-x64apache-tomcat-9.0.45-windows-x64apache-tomcat-9.0.45-windows-x64apache-tomcat-9.0.45-windows-x64apache-tomcat-9.0.45-windows-x64apache-...

    Tomcat源码apache-tomcat-8.5.47-src.zip

    1. **Catalina**:这是Tomcat的核心组件,负责管理Web应用程序,包括加载、部署、启动和停止应用。`org.apache.catalina`包下包含了大部分核心类,如`Engine`(顶层容器)、`Host`(虚拟主机)、`Context`(Web应用...

    Tomcat8亲测可用 tomcat-redis-session-manager的jar包

    1. **tomcat8**:这是Apache Tomcat的第八个主要版本,是一个开源的Java Servlet容器,它实现了Java EE的Web应用程序部署规范。Tomcat8支持Servlet 3.1、JSP 2.3和EL 3.0等标准。 2. **redis**:Redis是一种内存...

    tomcat-embed-core-9.0.16.jar

    tomcat-embed-core-9.0.16.jar

    apache-tomcat-7.0.81-src 源码免费下载

    4. **生命周期管理**:在`common`和`shared`目录中,可以看到Tomcat如何管理和控制各个组件的生命周期,包括启动、停止、初始化和销毁等过程。 5. **配置管理**:Tomcat的配置文件通常位于`conf`目录下,源码解析...

    centos源码安装apache-tomcat-8.0.21

    CentOS源码安装Apache Tomcat 8.0.21 Apache Tomcat是一款流行的Java Web服务器,广泛应用于企业级Web应用程序。CentOS是流行的Linux发行版,提供了稳定、安全的服务器环境。本文将指导您如何在CentOS系统上源码...

    Ant编译Tomcat源码、MyEclipse导入Tomcat源码、执行Tomcat源码启动Tomcat

    本篇将详细介绍如何使用Ant编译Tomcat源码,以及如何在MyEclipse环境中导入并运行Tomcat源码。 首先,Ant是Apache软件基金会开发的Java项目自动化构建工具,它能够执行编译、测试、打包等任务。在Apache Tomcat的...

    tomcat-connectors-1.2.48-src

    《深入理解Tomcat连接器:剖析tomcat-connectors-1.2.48-src源码》 Tomcat作为一款广泛使用的开源Java应用服务器,其在处理Web应用方面扮演着核心角色。而Tomcat的连接器(Connector)是其与外部世界交互的关键组件...

    apache-tomcat-6.0.35和apache-tomcat-6.0.35 src

    1. **Tomcat结构**: - **bin**:包含启动和停止Tomcat的脚本,如`catalina.sh/bat`、`startup.sh/bat`、`shutdown.sh/bat`等。 - **conf**:存放Tomcat配置文件,如`server.xml`(服务器配置)、`web.xml`(全局...

    tomcat 源码分析系列文档

    【标题】"Tomcat源码分析系列文档"深入解析了Apache Tomcat服务器的内部工作原理,涵盖了一系列关键知识点,如HTTP协议、类加载机制、容器设计模式等。这些文档为理解Tomcat的运行机制提供了宝贵的资源。 【描述】...

    tomcat-redis-session-manager支持tomcat7

    因tomcat7使用redis共享session,其他的包存在问题,自己编译后处理通过。 该包是在https://github.com/jcoleman/tomcat-redis-session-manager 将源码编译后的包。

    apache-tomcat-7.0.62-src和apache-tomcat-6.0.39-src的源码

    这个压缩包包含了两个版本的Tomcat源码:apache-tomcat-7.0.62-src和apache-tomcat-6.0.39-src,这两个版本分别代表了Tomcat在不同时间点的开发状态和技术特性。 首先,让我们从Apache Tomcat 6.0.39源码开始分析。...

    tomcat-connectors-1.2.32-src.tar.gz

    《Apache Tomcat Connectors源码解析与Linux环境下的整合指南》 Apache Tomcat Connectors,也被称为mod_jk或mod_proxy_ajp,是Apache HTTP Server与Tomcat应用服务器之间进行通信的重要桥梁。这个名为“tomcat-...

    tomcat8 tomcat-redis-session-manager

    tomcat8下 tomcat-redis-session-manager , github上有源码,其他版本都有打好的jar包,tomcat 8 下没有,下载源码生成了一个。

    apache-tomcat-6.0.53-src

    apache-tomcat-6.0.53-src,apache tomcat 6.0.53的源码。 压缩包文件清单: apache-tomcat-6.0.53-src.tar.gz apache-tomcat-6.0.53-src.tar.gz.asc apache-tomcat-6.0.53-src.tar.gz.md5 apache-tomcat-6.0.53-...

    tomcat8源码

    Apache Tomcat 8.5.23 源码分析 Apache Tomcat 是一个开源的、免费的Web服务器和Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,...因此,对Tomcat源码的学习对于Java Web开发者来说是至关重要的。

Global site tag (gtag.js) - Google Analytics