tomcat-类加载机制


 

tomcat类加载机制

When Tomcat is started, it creates a set of class loaders that areorganized into the following parent-child relationships, where the parentclass loader is above the child class loader:

      Bootstrap
          |
       System
          |
       Common
       /     \
  Webapp1   Webapp2 ...

Bootstrap — This class loader contains the basic runtime classes provided by the Java Virtual Machine, plus any classes from JAR files present in the SystemExtensions directory ($JAVA_HOME/jre/lib/ext).Note: some JVMs may implement this as more than one class loader, or it may not be visible (as a class loader) at all.

System —This class loader is normally initialized from the contents of theCLASSPATH environment variable。However, the standard Tomcat startup scripts ($CATALINA_HOME/bin/catalina.sh or%CATALINA_HOME%\bin\catalina.bat) totally ignore the contents of theCLASSPATH environment variable itself, and instead build the System class loader from the following repositories:

$CATALINA_HOME/bin/bootstrap.jar — Contains the main() method that is used to initialize the Tomcat server, and the class loader implementation classes it depends on.   main函数启动

$CATALINA_BASE/bin/tomcat-juli.jar or $CATALINA_HOME/bin/tomcat-juli.jar — Logging implementation classes. These include enhancement classes tojava.util.logging API, known as Tomcat JULI, and a package-renamed copy of Apache Commons Logging library used internally by Tomcat. Seelogging documentation for more details.  日志

$CATALINA_HOME/bin/commons-daemon.jar — The classes from Apache Commons Daemon project. This JAR file is not present in the CLASSPATH built bycatalina.bat|.sh scripts, but is referenced from the manifest file ofbootstrap.jar.


Common—this class loader are defined by the common.loader property in $CATALINA_BASE/conf/catalina.properties.

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar


WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the/WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the/WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

该classloader就有意违反委托模型,它首先看WEB-INF/classes和WEB-INF/lib里是否有请求的类,而不是委托parent classloader去加载。但是,JRE里定义的类不能被覆盖(比如java.lang.String,但也有一些特例,如 XML parser components),以及Servlet API会明确地被忽略。

前面说的bootstrap、system、common,都遵循普通的委托模型

从web app的角度来看,类或者资源加载是按照以下的顺序来查找的:

Bootstrap classes of your JVM(rt.jar)
System class loader classes(bootstrap.jar、tomcat-juli.jar、commons-deamon.jar)
/WEB-INF/classes of your web application
/WEB-INF/lib/*.jar of your web application
Common class loader classes (在$CATALINA_HOME/lib里的jar包)


tomcat类加载机制的建立过程:

由startup.bat 启动 catalina.bat,然后catalina.bat设置了CLASSPATH路径:

//------------------------------start: catalina.bat 设置CLASSPATH代码----------------------

set CLASSPATH=        // 先设置为空

。。。。

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"

//设置CLASSPATH=%CATALINA_HOME%\bin\bootstrap.jar
。。。

rem Add tomcat-juli.jar to classpath
rem tomcat-juli.jar can be over-ridden per instance
if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome
set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar"
goto juliClasspathDone


//设置CLASSPATH=%CATALINA_HOME%\bin\bootstrap.jar+tomcat-juli.jar

//------------------------------end: catalina.bat 设置CLASSPATH代码----------------------


然后由catalina.bat 启动Bootstrap.java中的main方法:


在main方法中调用bootstrap.init()--->

 

public static void main(String args[]) {

    if (daemon == null) {
        // Don't set daemon until init() has completed
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.init();//全局的系统属性、初始化类加载器、通过反射得到Catalina实例
        } 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);
    }

     。。。。
}

在init中调用initClassLoaders();

public void init()
    throws Exception
{

    // Set Catalina path
    setCatalinaHome();
    setCatalinaBase();

    initClassLoaders();

    。。。。 
}

在initClassLoaders中建立起tomcat 的类加载机制

SystemClassLoader<-CommonLoader(<-catalinaLoader<-sharedLoader  (已不再使用 ))

private void initClassLoaders() {
    try {
        commonLoader = createClassLoader("common", null);//null代表parent为SystemClassLoader,可以查看java源码
        if( commonLoader == null ) {
            // no config file, default to this loader - we might be in a 'single' env.
            commonLoader=this.getClass().getClassLoader();
        }
        Object appclassloader=commonLoader.getParent();//appclassloader
        catalinaLoader = createClassLoader("server", commonLoader);
        sharedLoader = createClassLoader("shared", commonLoader);
    } catch (Throwable t) {
        handleThrowable(t);
        log.error("Class loader creation threw exception", t);
        System.exit(1);
    }
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值