当前位置:web 服务器 > Tomcat >>

class卸载、热替换和Tomcat的热部署的分析

这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理。

一 class的热替换
ClassLoader中重要的方法
loadClass
      ClassLoader.loadClass(...) 是ClassLoader的入口点。当一个类没有指明用什么加载器加载的时候,JVM默认采用AppClassLoader加载器加载没有加载过的class,调用的方法的入口就是loadClass(...)。如果一个class被自定义的ClassLoader加载,那么JVM也会调用这个自定义的ClassLoader.loadClass(...)方法来加载class内部引用的一些别的class文件。重载这个方法,能实现自定义加载class的方式,抛弃双亲委托机制,但是即使不采用双亲委托机制,比如java.lang包中的相关类还是不能自定义一个同名的类来代替,主要因为JVM解析、验证class的时候,会进行相关判断。
 
defineClass
      系统自带的ClassLoader,默认加载程序的是AppClassLoader,ClassLoader加载一个class,最终调用的是defineClass(...)方法,这时候就在想是否可以重复调用defineClass(...)方法加载同一个类(或者修改过),最后发现调用多次的话会有相关错误:
...
java.lang.LinkageError
attempted duplicate class definition
...
所以一个class被一个ClassLoader实例加载过的话,就不能再被这个ClassLoader实例再次加载(这里的加载指的是,调用了defileClass(...)放方法,重新加载字节码、解析、验证。)。而系统默认的AppClassLoader加载器,他们内部会缓存加载过的class,重新加载的话,就直接取缓存。所与对于热加载的话,只能重新创建一个ClassLoader,然后再去加载已经被加载过的class文件。www.zzzyk.com

下面看一个class热加载的例子:
代码:HotSwapURLClassLoader自定义classloader,实现热替换的关键
  1 package testjvm.testclassloader;
  2
  3 import java.io.File;
  4 import java.io.FileNotFoundException;
  5 import java.net.MalformedURLException;
  6 import java.net.URL;
  7 import java.net.URLClassLoader;
  8 import java.util.HashMap;
  9 import java.util.Map;
 10
 11 /**
 12  * 只要功能是重新加载更改过的.class文件,达到热替换的作用
 13  * @author banana
 14  */
 15 public class HotSwapURLClassLoader extends URLClassLoader {
 16     //缓存加载class文件的最后最新修改时间
 17     public static Map<String,Long> cacheLastModifyTimeMap = new HashMap<String,Long>();
 18     //工程class类所在的路径
 19     public static String projectClassPath = "D:/Ecpworkspace/ZJob-Note/bin/";
 20     //所有的测试的类都在同一个包下
 21     public static String packagePath = "testjvm/testclassloader/";
 22    
 23     private static HotSwapURLClassLoader hcl = new HotSwapURLClassLoader();
 24    
 25     public HotSwapURLClassLoader() {
 26         //设置ClassLoader加载的路径
 27         super(getMyURLs());
 28     }
 29    
 30     public static HotSwapURLClassLoader  getClassLoader(){
 31         return hcl;
 32     }
 33
 34     private static  URL[] getMyURLs(){
 35         URL url = null;
 36         try {
 37             url = new File(projectClassPath).toURI().toURL();
 38         } catch (MalformedURLException e) {
 39             e.printStackTrace();
 40         }
 41         return new URL[] { url };
 42     }
 43    
 44     /**
 45      * 重写loadClass,不采用双亲委托机制("java."开头的类还是会由系统默认ClassLoader加载)
 46      */
 47     @Override
 48     public Class<?> loadClass(String name,boolean resolve) throws ClassNotFoundException {
 49         Class clazz = null;
 50         //查看HotSwapURLClassLoader实例缓存下,是否已经加载过class
 51         //不同的HotSwapURLClassLoader实例是不共享缓存的
 52         clazz = findLoadedClass(name);
 53         if (clazz != null ) {
 54             if (resolve){
 55                 resolveClass(clazz);
 56             }
 57             //如果class类被修改过,则重新加载
 58             if (isModify(name)) {
 59                 hcl = new HotSwapURLClassLoader();
 60                 clazz = customLoad(name, hcl);
 61             }
 62             return (clazz);
 63         }
 64
 65         //如果类的包名为"java."开始,则有系统默认加载器AppClassLoader加载
 66         if(name.startsWith("java.")){
 67             try {
 68                 //得到系统默认的加载cl,即AppClassLoader
 69                 ClassLoader system = ClassLoader.getSystemClassLoader();
 70                 clazz = system.loadClass(name);
 71                 if (clazz != null) {
 72                     if (resolve)
 73                         resolveClass(clazz);
 74                     return (clazz);
 75                 }
 76             } catch (ClassNotFoundException e) {

补充:综合编程 , 其他综合 ,
Apache
IIS
Nginx
Tomcat
如果你遇到web 服务器难题:
访问www.zzzyk.com 试试
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,