`

TOMCAT---类加载器

 
阅读更多

一、WebappClassLoader覆盖了classloader的loadclass方法

	public synchronized 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) 检查自身缓存:WebappClassLoader之前是否已经load过这个资源   
	clazz = findLoadedClass0(name);   
	        if (clazz != null) {   
	            if (log.isDebugEnabled())   
	                log.debug("  Returning class from cache");   
	            if (resolve)   
	                resolveClass(clazz);   
	            return (clazz);   
	        }   
	  
	        // (1) 检查上一级缓存:ClassLoader之前是否已经load过   
	        clazz = findLoadedClass(name);   
	        if (clazz != null) {   
	            if (log.isDebugEnabled())   
	                log.debug("  Returning class from cache");   
	            if (resolve)   
	                resolveClass(clazz);   
	            return (clazz);   
	        }   
	  
	        // (2) 先交由系统ClassLoader,因此WEB-INF/lib和WEB-INF/classes或{tomcat}/libs下的类定义不能覆盖JVM 底层能够查找到的定义(譬如不能通过定义java.lang.Integer替代底层的实现   
	        try {   
	            clazz = system.loadClass(name);   
	            if (clazz != null) {   
	                if (resolve)   
	                    resolveClass(clazz);   
	                return (clazz);   
	            }   
	        } catch (ClassNotFoundException e) {   
	            // Ignore   
	        }   
	  
	        // (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);   
	                }   
	            }   
	        }   
	  
	        //这是一个很奇怪的定义,JVM的ClassLoader建议先由parent去load,load不到自己再去load(见如上 ClassLoader部分),而Servelet规范的建议则恰好相反,Tomcat的实现则做个折中,由用户去决定(context的 delegate定义),默认使用Servlet规范的建议,即delegate=false   
	        boolean delegateLoad = delegate || filter(name);   
	  
	        // (1) 先由parent去尝试加载,此处的parent是SharedClassLoader,见如上说明,如上说明,除非设置了delegate,否则这里不执行   
	        if (delegateLoad) {   
	            if (log.isDebugEnabled())   
	                log.debug("  Delegating to parent classloader1 " + parent);   
	            ClassLoader loader = parent;   
	             //此处parent是否为空取决于context 的privileged属性配置,默认privileged=true,即parent为SharedClassLoader   
	            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) 到WEB-INF/lib和WEB-INF/classes目录去搜索,细节部分可以再看一下findClass,会发现默认是先搜索WEB-INF/classes后搜索WEB-INF/lib   
	        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) 由parent再去尝试加载一下   
	        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定义了自己的findclass方法

    public Class findClass(String name) 
//调用
    protected Class findClassInternal(String name)
//调用
    protected ResourceEntry findResourceInternal(String name, String path) {
....
        for (i = 0; (entry == null) && (i < repositoriesLength); i++) {
            try {

                String fullPath = repositories[i] + path;//repositories里面只有一个值,即:WEB-INF/classes

                Object lookupResult = resources.lookup(fullPath);
                if (lookupResult instanceof Resource) {
                    resource = (Resource) lookupResult;
                }

                // Note : Not getting an exception here means the resource was
                // found
                entry = findResourceInternal(files[i], path);

                ResourceAttributes attributes =
                    (ResourceAttributes) resources.getAttributes(fullPath);
                contentLength = (int) attributes.getContentLength();
                entry.lastModified = attributes.getLastModified();

                if (resource != null) {


                    try {
                        binaryStream = resource.streamContent();
                    } catch (IOException e) {
                        return null;
                    }

                    if (needConvert) {
                        if (path.endsWith(".properties")) {
                            fileNeedConvert = true;
                        }
                    }
....
                }

            } catch (NamingException e) {
            }
        }

        if ((entry == null) && (notFoundResources.containsKey(name)))//这里已经缓存了加载失败的类名字以提高性能。
            return null;

        JarEntry jarEntry = null;

        synchronized (jarFiles) {//如果在WEB-INF/classes中没找到则在CLASSPATH中JAR里找

            try {
                if (!openJARs()) {
                    return null;
                }
                for (i = 0; (entry == null) && (i < jarFilesLength); i++) {
    
                    jarEntry = jarFiles[i].getJarEntry(path);
    
                                   }
....

    }

 

分享到:
评论

相关推荐

    apache-tomcat-6.0.29.zip

    Tomcat作为Servlet容器,它会加载Servlet类,处理HTTP请求,并将结果返回给客户端。 2. **JavaServer Pages (JSP)**:JSP是Java Servlet的一种简化形式,允许开发人员将静态HTML与动态Java代码结合在一起,使网页...

    taobao-tomcat-7.0.59

    这些定制可能涉及内存管理、线程池、连接器优化、日志系统、安全管理等方面。 在【压缩包子文件的文件名称列表】中,"taobao-tomcat-7.0.59"可能包含了以下组件和目录: 1. `bin`:包含启动和停止Tomcat的脚本,如`...

    apache-tomcat-8.5.45-windows-x64.zip

    1. **Catalina**: 这是Tomcat的主要Servlet容器,负责加载、配置和管理Servlets。Catalina处理HTTP请求,并将这些请求转发给相应的Servlet进行处理。 2. **Jasper**: Jasper是Tomcat中的JSP编译器,它将JSP页面转换...

    apache-tomcat-7.0.59-x64.rar

    管理方面,Tomcat提供了内置的管理工具,如Manager App和Host Manager,它们可以通过Web界面进行部署、卸载、重新加载应用。要启用这些工具,需在users.xml中添加具有相应权限的用户,并在webapps/manager/META-INF/...

    tomcat-connectors-1.2.32-src.tar.gz

    5. 配置Tomcat:在Tomcat的conf/server.xml中添加AJP Connector,指定监听端口和连接器属性。 6. 创建workers.properties:定义Apache与Tomcat间的worker配置,包括worker类型、主机名、端口等信息。 7. 重启服务:...

    apache-tomcat-8.5.81.tar.gz

    Tomcat作为Servlet容器,负责加载、实例化和管理Servlet,使得开发者可以用Java编写服务器端逻辑。 2. **JSP (JavaServer Pages)**: JSP是Java Servlet的一种简化方式,允许开发者将HTML代码与Java代码混合,使页面...

    最新版windows apache-tomcat-10.0.0-windows-x64.zip

    一旦部署,Tomcat会自动解压并加载应用。 10. **社区支持**: - 作为开源项目,Apache Tomcat拥有庞大的开发者社区,提供持续的更新、bug修复和用户支持。开发者可以在官方论坛、邮件列表和GitHub上寻求帮助或参与...

    apache-tomcat-10.0.12.tar.gz

    `bin/catalina.sh`脚本提供了更多管理选项,如重新加载配置而不重启服务。 7. **安全性**:Tomcat的安全性是至关重要的,应配置SSL/TLS以加密通信,限制远程管理接口的访问,并定期更新到最新安全补丁以防止已知...

    apache-tomcat-8.0.30 linux 64位

    `startup.sh`用于启动Tomcat服务器,而`catalina.sh`则提供了更多的功能,如启动、停止、重新加载等操作。在某些情况下,你可能需要配置这两个脚本来适应你的系统环境。 配置主要涉及两个方面:设置Java环境变量和...

    apache-tomcat-5.5.26+apache-tomcat-5.5.26-admin.zip

    在Tomcat 5.5.26中,这可能包括Web管理界面,允许用户通过浏览器进行各种操作,如启动、停止和重新加载应用,查看服务器状态,管理用户角色和权限,以及部署新的Web应用。这个模块对于系统管理员来说非常有用,因为...

    apache-tomcat-9.0.52-linux.zip

    Tomcat支持集群配置,通过`cluster`元素在`server.xml`中设置,配合负载均衡器如Nginx或Apache HTTP Server可以实现这一功能。 10. **版本更新与维护**:为了保持系统的安全性和稳定性,定期检查并更新Tomcat到最新...

    tomcat-7.0.26.tomcat-juli.jar

    3. **性能优化**:与Apache Commons Logging相比,Juli避免了类加载器问题,减少了类查找的时间,从而提高了整体性能。 三、配置Juli 在Tomcat中,Juli的配置主要通过两个文件来完成: - **`conf/logging....

    apache-tomcat-7.0.94.zip

    Tomcat作为Servlet容器,负责加载和执行Servlet,处理HTTP请求,并向客户端发送响应。 2. **JSP(JavaServer Pages)**:JSP是Java Web开发中的视图层技术,允许开发者将静态HTML与动态Java代码结合起来创建网页。...

    apache-tomcat-8.0.47-windows-x64.zip 【Tomcat服务器,Tomcat8 windows 64位版】

    7. **Manager App**:一个内置的Web应用,允许通过Web界面管理部署在Tomcat上的应用,如部署、卸载、重新加载等操作。 8. **Host Manager App**:用于管理Tomcat服务器上的虚拟主机,可以创建、编辑和删除主机配置...

    apache-tomcat-8.0.35.exe下载

    开发者可以将自己编写的Web应用部署到"webapps"目录下,Tomcat会自动识别并加载这些应用。部署格式可以是WAR文件(Web应用程序归档文件),也可以是解压后的目录结构。此外,"conf/server.xml"是Tomcat的主要配置...

    apache-tomcat-8.5.37-windows-x86.zip

    Tomcat可以通过多种方式优化,如调整JVM参数(内存分配、垃圾回收策略等)、启用连接器(例如NIO或APR)以提升并发性能、使用负载均衡器等。 总之,Apache Tomcat 8.5.37 Windows x86版本是一个强大的Java Web...

    apache-tomcat-9.0.86-windows-x64.zip

    Tomcat作为Servlet和JSP的容器,负责加载、实例化和管理Servlet,以及将JSP转换成Servlet并执行。 2. **版本号**:“9.0.86”代表了Tomcat的主要版本和次要版本号,其中“9.0”表示主版本,而“86”是次版本。每个...

    官方原版apache-tomcat-8.5.51-windows-x64.zip 64位

    8. **endorsed目录**:这个目录用于放置那些需要覆盖Java标准库中的类的JAR文件,按照Java API的设计,这是通过在`endorsed`目录下的类优先级高于系统类加载器加载的类。 对于64位Windows用户,这个版本的Tomcat是...

    tomcat-connectors-1.2.40-windows-x86_64-httpd-2.4.x.zip mod_jk 64位

    此外,还需要在Tomcat的`conf/server.xml`文件中配置AJP监听器,以便Tomcat可以接收来自`mod_jk`的请求。通过这种方式,Apache HTTP Server可以作为前端服务器处理静态内容,而Tomcat则专注于处理Java Web应用程序,...

    官方原版tomcat-9.0.29 64位

    - **缓存设置**:启用JVM的类加载器缓存和Tomcat的Web应用程序资源缓存,减少I/O操作。 6. **安全与维护**: - **定期更新**:保持Tomcat版本及时更新,避免已知的安全漏洞。 - **安全配置**:配置`conf/web.xml...

Global site tag (gtag.js) - Google Analytics