tomcat安全加载CLASS分析

来源:互联网 发布:linux edonkey 编辑:程序博客网 时间:2024/06/13 03:31

前言

在《通过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加载进来了

0 0
原创粉丝点击