inside tomcat 技术内幕

本文详细介绍了如何从官网下载并编译Tomcat7源码,使用Eclipse导入源码进行编译,以及如何运行整个工程并深入分析启动过程。主要内容包括初始化类加载器、加载与启动步骤,以及Catalina类在实际启动工作中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

几年的编程生涯,多少积累了些技术经验。是时候更深入的研究和总结一下了。就拿最常用的tomcat 7为例。废话不多说,下面开始干活。
1. 从官网download下源码:
http://mirrors.hust.edu.cn/apache/tomcat/tomcat-7/v7.0.65/src/apache-tomcat-7.0.65-src.zip
解压Tomcat源码,如解压到D:\share\apache-tomcat-7.0.59-src。
2. 用ant编译源码。可以download官网也可以用eclipse自带的ant编译。
这里直接用eclipse导入源码编译。
eclipse –> new java project,起一个工程名为Tomcat7,然后import 源码到工程目录下。
这里还要将Tomcat7工程下的build.properties.default重命名为build.properties,并编辑修改base.path=E:/eclipseWork/Tomcat7/repository。
右键build.xml–>run as Ant Build,执行ant编译,这里注意编译环境选择JDK1.6,选JDK1.7会报错。成功会生成output目录。
还要加入依赖的jar包:jaxrpc-1.1.jar,org.eclipse.jdt.core-3.7.1.jar,wsdl4j-1.6.2.jar。
3. 运行。整个工程的入口在Bootstrap.java main方法里。
执行 右键run as:在VM arguments参数加上
-Dcatalina.home=”E:\eclipseWork\Tomcat7\output\build”,启动完成。

  1. 启动过程分析。
    整个程序的入口是Bootstrap.main()这个引导加载类。
    查看main方法源码大致如下:
public static void main(String args[]) {
    ...
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.init();
    daemon.load(args);
    daemon.start();
    ...
}

可以看出,程序的启动分三步,初始化init、加载load和启动start。
bootstrap.init();方法代码:

public void init() {
    initClassLoaders();             
    Thread.currentThread().setContextClassLoader(catalinaLoader);
    Class<?> startupClass =
            catalinaLoader.loadClass
            ("org.apache.catalina.startup.Catalina");
    Object startupInstance = startupClass.newInstance();
    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;        
}

private void initClassLoaders() {        
     commonLoader = createClassLoader("common", null);            
     commonLoader=this.getClass().getClassLoader();            
     catalinaLoader = createClassLoader("server", commonLoader);
     sharedLoader = createClassLoader("shared", commonLoader);        
}

可以看出初始化首先初始化几个类加载器classLoader,利用反射实例化一个Catalina类实例,并把刚刚刚初始化的classLoader设置为成员变量。

private void load(String[] arguments)
        throws Exception {

        // Call the load() method
        String methodName = "load";
        Object param[];
        Class<?> paramTypes[];
        paramTypes = null;
        param = null;
        Method method =
            catalinaDaemon.getClass().getMethod(methodName, paramTypes);
        method.invoke(catalinaDaemon, param);
    }
 public void start()
        throws Exception {
        if( catalinaDaemon==null ) init();
        Method method = catalinaDaemon.
            getClass().getMethod("start", (Class [] )null);
        method.invoke(catalinaDaemon, (Object [])null);
    }

load和start方法都是通过调用刚才实例化catalina实例的对应load, start方法。可以看出整个程序的实际启动工作其实是在Catalina类中实现。那么为什么要这么做呢,而不是直接用Catalina启动?其目的就是隐藏该类实例,让应用程序不可见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值