• 细说tomcat之类加载器


    官网:http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
    Java类加载与Tomcat类加载器层级关系对比

    Java ClassLoader:                         
        Bootstrap ClassLoader(加载$JAVA_HOME/jre/lib/目录下核心类库:resources.jar,rt.jar,sunrsasign.jar,jsse.jar,jce.jar,charsets.jar,jfr.jar,以及jre/classes目录下的class)                 
           /|
            |                                                            Tomcat ClassLoader:      
        ExtClassLoader(加载$JAVA_HOME/jre/lib/ext/目下的所有jar) -------- Bootstrap(加载$JAVA_HOME/jre/lib/ext/目录下的所有jar)
           /|                                                                 /|
            |                                                                   |     
        AppClassLoader(加载应用程序classpath目录下的所有jar和class文件)    System(加载$CATALINA_HOME/bin/bootstrap.jar,$CATALINA_BASE/bin/tomcat-juli.jar,$CATALINA_HOME/bin/commons-daemon.jar)
                                                                               /|
                                                                                |
                                                                             Common(加载$CATALINA_BASE/lib和$CATALINA_HOME/lib下的class,资源和jar文件)
                                                                               /|
                                                                                |
                                                                             WebAppClassLoader(加载WebApp/WEB-INF/classes,WebApp/WEB-INF/lib)
    

    Java ClassLoader验证:

    public class ClassLoaderTest {
        public static void main(String[] args) {
            ClassLoader appClassLoader = ClassLoaderTest.class.getClassLoader();
            ClassLoader extClassLoader = appClassLoader.getParent();
            ClassLoader bootstrapClassLoader = extClassLoader.getParent();
            System.out.println(appClassLoader);
            System.out.println(extClassLoader);
            System.out.println(bootstrapClassLoader);
        }
    }
    输出:
    sun.misc.Launcher$AppClassLoader@73d16e93
    sun.misc.Launcher$ExtClassLoader@15db9742
    nul

    Tomcat ClassLoader验证:

    public class ClassLoaderServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ClassLoader loader = this.getClass().getClassLoader();
            while(loader != null) {
                System.out.println(loader);
                loader = loader.getParent();
            }
            System.out.println(loader);
        }
    }

    输出:
    ParallelWebappClassLoader
      context: test-web
      delegate: false
    ----------> Parent Classloader:
    java.net.URLClassLoader@379619aa

    java.net.URLClassLoader@379619aa
    sun.misc.Launcher$AppClassLoader@764c12b6
    sun.misc.Launcher$ExtClassLoader@1a93a7ca
    null

    跟踪org.apache.catalina.loader.ParallelWebappClassLoader源码发现,org.apache.catalina.loader.WebappClassLoaderBase重写了toString()方法:

    @Override
    public String toString() {
    
        StringBuilder sb = new StringBuilder(this.getClass().getSimpleName());
        sb.append("
      context: ");
        sb.append(getContextName());
        sb.append("
      delegate: ");
        sb.append(delegate);
        sb.append("
    ");
        if (this.parent != null) {
            sb.append("----------> Parent Classloader:
    ");
            sb.append(this.parent.toString());
            sb.append("
    ");
        }
        if (this.transformers.size() > 0) {
            sb.append("----------> Class file transformers:
    ");
            for (ClassFileTransformer transformer : this.transformers) {
                sb.append(transformer).append("
    ");
            }
        }
        return (sb.toString());
    }

    也就是说,Tomcat的ClassLoader结构为:

    null(JVM Bootstrap ClassLoader)
    sun.misc.Launcher$ExtClassLoader@1a93a7ca
    sun.misc.Launcher$AppClassLoader@764c12b6
    java.net.URLClassLoader@379619aa
    org.apache.catalina.loader.ParallelWebappClassLoader

    Tomcat Common ClassLoader默认的搜索顺序为:

    (1)unpacked classes and resources in $CATALINA_BASE/lib
    (2)JAR files in $CATALINA_BASE/lib
    (3)unpacked classes and resources in $CATALINA_HOME/lib
    (4)JAR files in $CATALINA_HOME/lib

    Tomcat classloader类图

    总结:
    1. Java装载类使用“全盘负责委托机制”。
    “全盘负责”是指当一个ClassLoder装载一个类时,除非显示地使用另外一个ClassLoder,否则该类所依赖及引用的类也由这个ClassLoder载入;
    “委托机制”是指先委托父类装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。
    2. Tomcat的WebAppClassLoade默认不使用“委托机制”,查找class和资源的顺序如下:

    (1)Bootstrap classes of your JVM
    (2)/WEB-INF/classes of your web application
    (3)/WEB-INF/lib/*.jar of your web application
    (4)System class loader classes
    (5)Common class loader classes
    If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:
    (1)Bootstrap classes of your JVM
    (2)System class loader classes
    (3)Common class loader classes
    (4)/WEB-INF/classes of your web application
    (5)/WEB-INF/lib/*.jar of your web application

    3. Tomcat中变量CATALINA_BASE和CATALINA_HOME的含义

    Throughout the docs, you'll notice there are numerous references to $CATALINA_HOME的含义.
    This represents the root of your Tomcat installation. When we say, "This information can be found in your $CATALINA_HOME/README.txt file" we mean to look at the README.txt file at the root of your Tomcat install.
    Optionally, Tomcat may be configured for multiple instances by defining $CATALINA_BASE for each instance. If multiple instances are not configured, $CATALINA_BASE is the same as $CATALINA_HOME.

    一言以蔽之:如果没有明确设置CATALINA_BASE变量,则CATALINA_BASE与CATALINA_HOME值相同,都是值tomcat安装目录。

    【参考】
    http://www.hollischuang.com/archives/199 深度分析Java的ClassLoader机制(源码级别)
    http://blog.csdn.net/xyang81/article/details/7292380  深入分析Java ClassLoader原理

  • 相关阅读:
    TKStudio示例工程LPC1220_GPIO_LED学习
    LIve Writer图片自动水印,自动居中,自动为原始大小的设置方法.
    cmd 修改文件属性
    [原创]Java下X86机,Bytes和Int的转换
    [原创]把","号分隔的字串转化成一列的Table
    [原创]Java实现PKCS7填充的DES加密(修订版)
    利用ADODB.Stream实现 Bytes到String的指定编码的转换
    [原创]利用HttpModuler实现WEB程序同一时间只让一个用户实例登陆(修改)
    [原创]用XMLHttp BinaryWrite,Post GB2312编码的字串
    UTF8ToBytes
  • 原文地址:https://www.cnblogs.com/nuccch/p/7071446.html
Copyright © 2020-2023  润新知