tomcat安全加载CLASS分析

前言

《通过tomcat源码查看其如何实现应用相互隔离》中,我介绍了在Bootstrap的init方法中,其中有关类加载器的执行有3步:

  1. 初始化commonLoader、catalinaLoader和sharedLoader;
  2. 将catalinaLoader设置为Tomcat主线程的线程上下文类加载器;
  3. 线程安全的加载class。

这篇博客就是介绍如何tomcat线程安全的加载class。

安全加载CLASS分析

首先来看Bootstrap的init方法,见代码清单1

                            代码清单1
    /**
     * Initialize daemon.
     */


     public void init()
        throws Exception
    {

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

        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);

        catalinaDaemon = startupInstance;

    }

其中SecurityClassLoad.securityClassLoad(catalinaLoader)的作用就是线程安全的加载class,该方法代码见代码清单2。

                            代码清单2
    public static void securityClassLoad(ClassLoader loader)
        throws Exception {

        if( System.getSecurityManager() == null ){
            return;
        }

        loadCorePackage(loader);
        loadLoaderPackage(loader);
        loadSessionPackage(loader);
        loadUtilPackage(loader);
        loadJavaxPackage(loader);
        loadCoyotePackage(loader);       
        loadTomcatPackage(loader);
    }

securityClassLoad方法主要负责加载Tomcat容器所需的class,包括:

  • Tomcat核心class,即org.apache.catalina.core路径下的class;
  • org.apache.catalina.loader.WebappClassLoader$PrivilegedFindResourceByName;
  • Tomcat有关session的class,即org.apache.catalina.session路径下的class;
  • Tomcat工具类的class,即org.apache.catalina.util路径下的class;
  • javax.servlet.http.Cookie;
  • Tomcat处理请求的class,即org.apache.catalina.connector路径下的class;
  • Tomcat其它工具类的class,也是org.apache.catalina.util路径下的class;

以加载Tomcat核心class的loadCorePackage方法为例(见代码清单3),查看其实现。

                            代码清单3
    private final static void loadCorePackage(ClassLoader loader)
        throws Exception {
        String basePackage = "org.apache.catalina.";
        loader.loadClass
            (basePackage +
            "core.ApplicationContextFacade$1");
        loader.loadClass
            (basePackage +
            "core.ApplicationDispatcher$PrivilegedForward");
        loader.loadClass
            (basePackage +
            "core.ApplicationDispatcher$PrivilegedInclude");
        loader.loadClass
            (basePackage +
            "core.AsyncContextImpl");
        loader.loadClass
            (basePackage +
            "core.AsyncContextImpl$AsyncState");
        loader.loadClass
            (basePackage +
            "core.AsyncContextImpl$DebugException");
        loader.loadClass
            (basePackage +
            "core.AsyncContextImpl$1");
        loader.loadClass
            (basePackage +
            "core.AsyncContextImpl$2");
        loader.loadClass
            (basePackage +
            "core.AsyncListenerWrapper");
        loader.loadClass
            (basePackage +
            "core.ContainerBase$PrivilegedAddChild");
        loader.loadClass
            (basePackage +
            "core.DefaultInstanceManager$1");
        loader.loadClass
            (basePackage +
            "core.DefaultInstanceManager$2");
        loader.loadClass
            (basePackage +
            "core.DefaultInstanceManager$3");
        loader.loadClass
            (basePackage +
            "core.DefaultInstanceManager$4");
        loader.loadClass
            (basePackage +
            "core.DefaultInstanceManager$5");
        loader.loadClass
            (basePackage +
            "core.ApplicationHttpRequest$AttributeNamesEnumerator");
    }

其余的与此类似。这样就将tomcat的class加载进来了

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页