`
klcwt
  • 浏览: 195739 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Tomcat webAppClassloader

阅读更多

     WebappClassLoader  继承了URLClassLoader里面加入缓存和安全。

     缓存:

          1.缓存了已经事先装载的Classes。

          2.缓存了错误信息,比如先前装载一个类报错,那么下次再load这个类的时候,就会到缓存中去查找

           (   ClassNotFoundException

 

 

 

 /**
     * Load the class with the specified name.  This method searches for
     * classes in the same manner as <code>loadClass(String, boolean)</code>
     * with <code>false</code> as the second argument.
     *
     * @param name Name of the class to be loaded
     *
     * @exception ClassNotFoundException if the class was not found
     */
    public Class loadClass(String name) throws ClassNotFoundException {

        return (loadClass(name, false));

    }


    /**
     * Load the class with the specified name, searching using the following
     * algorithm until it finds and returns the class.  If the class cannot
     * be found, returns <code>ClassNotFoundException</code>.
     * <ul>
     * <li>Call <code>findLoadedClass(String)</code> to check if the
     *     class has already been loaded.  If it has, the same
     *     <code>Class</code> object is returned.</li>
     * <li>If the <code>delegate</code> property is set to <code>true</code>,
     *     call the <code>loadClass()</code> method of the parent class
     *     loader, if any.</li>
     * <li>Call <code>findClass()</code> to find this class in our locally
     *     defined repositories.</li>
     * <li>Call the <code>loadClass()</code> method of our parent
     *     class loader, if any.</li>
     * </ul>
     * If the class was found using the above steps, and the
     * <code>resolve</code> flag is <code>true</code>, this method will then
     * call <code>resolveClass(Class)</code> on the resulting Class object.
     *
     * @param name Name of the class to be loaded
     * @param resolve If <code>true</code> then resolve the class
     *
     * @exception ClassNotFoundException if the class was not found
     */
    public Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException {

        if (log.isDebugEnabled())
            log.debug("loadClass(" + name + ", " + resolve + ")");
        Class clazz = null;

        // Log access to stopped classloader
        if (!started) {
            try {
                throw new IllegalStateException();
            } catch (IllegalStateException e) {
                log.info(sm.getString("webappClassLoader.stopped", name), e);
            }
        }

        // (0) Check our previously loaded local class cache
        //在这里装载的时候使用了缓存,注意这个是local class 


        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (log.isDebugEnabled())
                log.debug("  Returning class from cache");
            if (resolve)
                resolveClass(clazz);
            return (clazz);
        }

        // (0.1) Check our previously loaded class cache
        //而这个就是class


        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (log.isDebugEnabled())
                log.debug("  Returning class from cache");
            if (resolve)
                resolveClass(clazz);
            return (clazz);
        }

        // (0.2) Try loading the class with the system class loader, to prevent
        //       the webapp from overriding J2SE classes
        try {
            clazz = system.loadClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return (clazz);
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }

        // (0.5) Permission to access this class when using a SecurityManager
        //安全机制


        if (securityManager != null) {
            int i = name.lastIndexOf('.');
            if (i >= 0) {
                try {
                    securityManager.checkPackageAccess(name.substring(0,i));
                } catch (SecurityException se) {
                    String error = "Security Violation, attempt to use " +
                        "Restricted Class: " + name;
                    log.info(error, se);
                    throw new ClassNotFoundException(error, se);
                }
            }
        }

        boolean delegateLoad = delegate || filter(name);
        
        // (1) Delegate to our parent if requested
        //代理装载类


        if (delegateLoad) {
            if (log.isDebugEnabled())
                log.debug("  Delegating to parent classloader1 " + parent);
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            try {
                clazz = loader.loadClass(name);
                if (clazz != null) {
                    if (log.isDebugEnabled())
                        log.debug("  Loading class from parent");
                    if (resolve)
                        resolveClass(clazz);
                    return (clazz);
                }
            } catch (ClassNotFoundException e) {
                ;
            }
        }

        // (2) Search local repositories
        if (log.isDebugEnabled())
            log.debug("  Searching local repositories");
        try {
            clazz = findClass(name);
            if (clazz != null) {
                if (log.isDebugEnabled())
                    log.debug("  Loading class from local repository");
                if (resolve)
                    resolveClass(clazz);
                return (clazz);
            }
        } catch (ClassNotFoundException e) {
            ;
        }

        // (3) Delegate to parent unconditionally
        if (!delegateLoad) {
            if (log.isDebugEnabled())
                log.debug("  Delegating to parent classloader at end: " + parent);
            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            try {
                clazz = loader.loadClass(name);
                if (clazz != null) {
                    if (log.isDebugEnabled())
                        log.debug("  Loading class from parent");
                    if (resolve)
                        resolveClass(clazz);
                    return (clazz);
                }
            } catch (ClassNotFoundException e) {
                ;
            }
        }

        throw new ClassNotFoundException(name);
    }
 

    看看WebAppClassLoader是如何从缓存中装载的

 

    /**
     * Finds the class with the given name if it has previously been
     * loaded and cached by this class loader, and return the Class object.
     * If this class has not been cached, return <code>null</code>.
     *
     * @param name Name of the resource to return
     */
    protected Class findLoadedClass0(String name) {
        //resouceEntries是个hashmap


        ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
        if (entry != null) {
            return entry.loadedClass;
        }
        return (null);  // FIXME - findLoadedResource()

    }


  //看看缓存对象的代码 
  import java.net.URL;
import java.security.cert.Certificate;
import java.util.jar.Manifest;

/**
 * Resource entry.
 *
 * @author Remy Maucherat
 * @version $Revision: 302726 $ $Date: 2004-02-27 15:59:07 +0100 (ven., 27 f茅vr. 2004) $
 */
public class ResourceEntry {


    /**
     * The "last modified" time of the origin file at the time this class
     * was loaded, in milliseconds since the epoch.
     */
    public long lastModified = -1;


    /**
     * Binary content of the resource.
     */
    public byte[] binaryContent = null;


    /**
     * Loaded class.
     */
    public Class loadedClass = null;


    /**
     * URL source from where the object was loaded.
     */
    public URL source = null;


    /**
     * URL of the codebase from where the object was loaded.
     */
    public URL codeBase = null;


    /**
     * Manifest (if the resource was loaded from a JAR).
     */
    public Manifest manifest = null;


    /**
     * Certificates (if the resource was loaded from a JAR).
     */
    public Certificate[] certificates = null;
}


 

   安全机制

 

/**
     * The set of trigger classes that will cause a proposed repository not
     * to be added if this class is visible to the class loader that loaded
     * this factory class.  Typically, trigger classes will be listed for
     * components that have been integrated into the JDK for later versions,
     * but where the corresponding JAR files are required to run on
     * earlier versions.
     */
    protected static final String[] triggers = {
        "javax.servlet.Servlet"                     // Servlet API
    };

//这个在Tomcat4中有,在tomcat6.0中没有


private static final String[] packageTriggers = {
  "javax",                                     // Java extensions
  "org.xml.sax",                               // SAX 1 & 2
  "org.w3c.dom",                               // DOM 1 & 2
  "org.apache.xerces",                         // Xerces 1 & 2
  "org.apache.xalan"                           // Xalan
};




 

 

分享到:
评论

相关推荐

    tomcat 源码分析系列文档

    3. "理解Tomcat的WebappClassLoader(web应用类加载器)一.doc":进一步探讨WebappClassLoader的工作机制,包括类查找策略、双亲委派模型的实现及其在多web应用环境下的应用。 4. "Tomcat源码分析(4)容器处理链接之...

    tomcat8源码

    主要有CommonClassLoader、SharedClassLoader和WebappClassLoader,它们按层次加载类。 5. **连接器(Connector)与协议处理器(Protocol Handler)** - **Coyote Connector**:Tomcat的Coyote组件负责接收和发送...

    tomcat6异常问题

    7. **使用隔离的类加载器**:通过设置不同的类加载策略,例如Web应用的`WebappClassLoader`,可以避免不同应用之间的jar冲突。 8. **社区支持**:在Apache Tomcat的官方论坛或Stack Overflow等技术社区提问,获取...

    简单的Tomcat源码实现

    2. **类加载机制**:Tomcat使用自定义的类加载器,如`CommonClassLoader`、`WebappClassLoader`等,以实现不同Web应用间的隔离。 3. **请求处理**:` CoyoteAdapter`是Servlet容器与Tomcat网络接口(Coyote)之间的...

    Tomcat8.0底层源码

    `WebappClassLoader`则负责加载应用的类和资源文件。 四、线程模型 Tomcat采用基于线程池的并发模型,`Executor`接口及其实现类`ThreadPoolExecutor`用于管理线程。默认情况下,Tomcat使用`AprLifecycleListener`...

    tomcat源码学习

    理解`org.apache.catalina.loader`包下的`WebappClassLoader`及其工作原理,是深入理解Tomcat多应用隔离的关键。 6. **线程池和并发模型**:Tomcat使用线程池处理请求,以提高并发性能。理解`Executor`和线程管理...

    Tomcat 作为单机板注册成为服务

    - `-Dorg.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false`:解决Tomcat重新加载Web应用时,不清除class文件中static和final变量的值而导致的潜在问题。 - `-Duser.timezone=GMT+08`:...

    Tomcat面试专题.pdf

    12. **类加载及对象回收**:了解Tomcat的类加载机制(如WebAppClassLoader),并使用JVM工具跟踪对象创建和销毁。 13. **请求处理过程**:一个完整的请求从HTTP客户端发起,经过网络传输到达Tomcat,被Connector...

    Maven工程Tomcat热部署详解.pdf

    一旦检测到变化,Tomcat会停止应用的启动线程,清除引用,并将加载该应用的WebappClassLoader置为null,然后创建一个新的WebappClassLoader实例重新加载应用。 在Maven工程中配置Tomcat热部署,需要在pom.xml文件中...

    细说Tomcat如何打破双亲委派(有源码和图)

    Tomcat作为一款广泛使用的Java应用服务器,其类加载机制有着独特的设计,特别是对Java的双亲委派模型有所突破。本篇文章将深入探讨Tomcat如何打破双亲委派模型,并通过源码分析和图表解析来帮助理解这一机制。 首先...

    Tomcat7 负载Jar包

    4. **使用WebAppClassLoader**:针对特定应用的JAR,应放在Web应用的`WEB-INF/lib`下,由WebAppClassLoader加载。 **三、配置文件详解** 1. **server.xml**:这是Tomcat的主要配置文件,包含了Server、Service、...

    howtomcatworks tomcat运行内幕

    Tomcat的类加载机制遵循“父类加载优先”原则,通过`CommonLoader`、`CatalinaLoader`、`SharedLoader`和`WebappClassLoader`四个层次进行加载,保证了不同Web应用之间的类隔离。 8. **安全性** Tomcat支持多种...

    Problem with WebappClassLoader in background thread

    在Java的Web应用开发中,WebappClassLoader是Tomcat等Servlet容器用于加载应用中类的特定类加载器。它负责加载Web应用程序的类和资源,确保每个Web应用都有自己的类加载器实例,从而实现类的隔离。 该问题可能涉及...

    spring-instrument-tomcat-4.3.14.RELEASE.jar

    Tomcat's WebappClassLoader is currently not instrumentable, so Spring provides a custom ClassLoader that can be used by placing spring-instrument-tomcat.jar in $TOMCAT_HOME/lib and putting a loader ...

    how-tomcat-works

    Tomcat使用WebappLoader和WebappClassLoader来加载Web应用的类,并监控类的改动,实现热部署。 七、Session管理 Tomcat提供了对HTTP会话(Session)的管理,包括创建、存储和销毁Session,以及在集群环境下的...

    Tomcat 5.0.18 ClassLoader source code insight

    通过阅读`WebappClassLoader`的源码,结合实际的Tomcat部署经验,我们可以更深刻地理解类加载机制,这对于解决复杂的应用问题和提升性能优化能力具有极大的帮助。在学习过程中,可以参考博客文章(如提供的链接)和...

    tomcat6源码,学习服务引擎

    5. **类加载**:探究`org.apache.catalina.loader.WebappClassLoader`,了解如何加载Web应用的类。 6. **部署与卸载**:了解`org.apache.catalina.manager.ManagerBase`和`org.apache.catalina.startup....

Global site tag (gtag.js) - Google Analytics