zoukankan      html  css  js  c++  java
  • Tomcat学习笔记(八)

      Tomcat载入器(二)

       Tomcat拥有不同的自定义类加载器,以实现对各种资源库的控制。

       1.同一个web服务器里,各个web项目之间各自使用的java类库要互相隔离。

       2.同一个web服务器里,各个web项目之间可以提供共享的java类库。

       3.为了是服务器不受web项目的影响,应该使服务器的类库与应用程序的类库互相对立。

       4.对于支持JSP的web服务器,应该支持热插拔功能。 在Tomcat中,最重要的一个类加载器是Common类加载器,它的父类加载器是应用程序类加载器,负责加载$CATALINA_BASE/lib、$CATALINA_HOME/lib两个目录下所有的.class文件和.jar文件。

                                                       

                 在Tomcat中,最重要的一个类加载器是Common类加载器,它的父类加载器是应用程序类加载器,负责加载$CATALINA_BASE/lib、$CATALINA_HOME/lib两个目录下

    所有的.class文件和.jar文件。

    其中:

    • Bootstrap - 载入JVM自带的类和$JAVA_HOME/jre/lib/ext/*.jar
    • System - 载入$CLASSPATH/*.class
    • Common - 载入$CATALINA_HOME/common/…,它们对TOMCAT和所有的WEB APP都可见
    • Catalina - 载入$CATALINA_HOME/server/…,它们仅对TOMCAT可见,对所有的WEB APP都不可见
    • Shared - 载入$CATALINA_HOME/shared/…,它们仅对所有WEB APP可见,对TOMCAT不可见(也不必见)
    • WebApp? - 载入ContextBase?/WEB-INF/…,它们仅对该WEB APP可见

            2 、ClassLoader的工作原理 每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类 系统默认的contextClassLoader是systemClassLoader,

    所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类 可以使用Thread.currentThread().setContextClassLoader(...);

    更改当前线程的contextClassLoader,来改变其载入类的行为 ClassLoader被组织成树形,一般的工作原理是:

               1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类

               2) contextClassLoader请求它的父ClassLoader来完成该载入请求

               3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入

              注意:WebApp?ClassLoader的工作原理和上述有少许不同:它先试图自己载入类(在ContextBase?/WEB-INF/...中载入类),如果无法载入,再请求父ClassLoader完成 。

              由此可得:

                     对于WEB APP线程,它的contextClassLoader是WebApp?ClassLoader

                     对于Tomcat Server线程,它的contextClassLoader是CatalinaClassLoader

            3、部分源码分析

            (1)初始化类加载器

    private void initClassLoaders() {
            try {
                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);
            }
        }

          (2)类加载工厂ClassLoaderFactory

                              

                       简要说明一下:Repository表示资源。RepositoryType枚举类型的资源的类型。使用createClassLoader方法来创建类加载器。

    public static ClassLoader createClassLoader(List<Repository> repositories, final ClassLoader parent)

    在JVM中,一个类由完全匹配类名和一个类加载器的实例ID作为唯一标识。也就是说,同一个虚拟机可以有两个包名、类名都相同的类,只是它们有不同的类加载器加载,而在各自类加载中的类实例也是不同的,并且不能互相转换。

    为了避免类加载的错误,应该尽早的设置是下文类加载器,所以tomcat初始化的时候就进行Thread.currentThread().setContextClassLoader(catalinaLoader);

  • 相关阅读:
    AngularJs学习笔记--directive
    angularjs 路由(1)
    走进AngularJs(一)angular基本概念的认识与实战
    angularjs- 快速入门
    从angularJS看MVVM
    中软国际 问题一php的优缺点
    elasticsearch head安装后无法连接到es服务器问题
    Laravel5.3 流程粗粒度分析之bootstrap
    mysql执行大量sql语句
    Laravel RuntimeException inEncrypter.php line 43: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths
  • 原文地址:https://www.cnblogs.com/lzeffort/p/7082857.html
Copyright © 2011-2022 走看看