zoukankan      html  css  js  c++  java
  • tomcat中的类加载机制

    Tomcat中的类加载机制符合JVM推荐的双亲委派模型,关于JVM的类加载机制不多说,网上很多资料。

    1. Tomcat类加载器过程。

    tomcat启动初始化阶段创建几个类加载器:

        private void initClassLoaders() {
            try {
                //aaa
                commonLoader = createClassLoader("common", null);
                if( commonLoader == null ) {
                    // no config file, default to this loader - we might be in a 'single' env.
                    commonLoader=this.getClass().getClassLoader();
                }
                catalinaLoader = createClassLoader("server", commonLoader);
                sharedLoader = createClassLoader("shared", commonLoader);
            } catch (Throwable t) {
                handleThrowable(t);
                log.error("Class loader creation threw exception", t);
                System.exit(1);
            }
        }

    Bootstrap启动时创建三个URLClassLoader :  common , catalina, shared

    接下来:

            initClassLoaders();
    
            Thread.currentThread().setContextClassLoader(catalinaLoader);
    
            SecurityClassLoad.securityClassLoad(catalinaLoader);
    
            // 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[] = 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);

    红色部分的代码 是将 Catalina 对象的父类加载器设置为 shared 加载器。之后,在Tomcat其他组件(Server , Service , Container 等)获取得到的父类加载都是 shared 加载器,

    当创建 WebappClassLoader(即 应用程序类加载器)时指定 的父加载器是 shared加载器,网上包括一部分讲解tomcat的书里说到应用程序类加载器 的 父加载器是 common,其实是不准确的,只是默认配置下, shared 加载器 就是 common加载器。

    tomcat加载类的顺序

    查看WebappClassLoaderBase.loadClass()源码,可以很清楚的了解类加载顺序:

    • 在 tomcat 已加载类的列表中查找
    • 在jvm已加载类的列表中查找
    • 尝试从JVM系统库({java.home}/jre/lib和{java.home}/jre/lib/ext)加载
    • 尝试从tomcat中的当前web应用的/WEB-INF/classes目录下加载     
    • 尝试从tomcat中的当前web应用的/WEB-INF/lib目录下加载
    • 尝试从tomcat shared指定的类库中加载
    • 尝试从tomcat common指定的类库中加载
    • 尝试使用系统类加载器(AppClassLoader)在classpath中加载(使用Class.forName()方法)

    如果上述步骤都没有加载到类,就会抛出ClassNotFoundException

    2. Tomcat 类库和 web应用类库的共享与隔离

    有四种逻辑关系:

    •     tomcat类库与web应用隔离类库 , 由catalina类加载器来实现
    •     tomcat类库与web应用共享类库,由common类加载器来实现
    •     多个web应用共享类库,由shared类加载器来实现
    •     多个web应用隔离类库,由一个web应用对应一个唯一的应用程序类加载器来实现(WebappClassLoader)

    catalina,common,shared的配置在conf/catalina.properties中

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

    server.loader=

    shared.loader= 

  • 相关阅读:
    (二)处理视频
    vim下多行注释与解注释
    (一)读取显示图片
    解决死锁的方法
    死锁、活锁和饿死的理解(转)
    C# winfrom 窗体的StartPosition 属性
    Show()和ShowDialog()
    WinForm应用程序之注册模块的设计与实现
    Epplus使用教程1(基本介绍)
    C#中操作txt,抛出“正由另一进程使用,因此该进程无法访问此文件”
  • 原文地址:https://www.cnblogs.com/selfchange/p/7521810.html
Copyright © 2011-2022 走看看