欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实现类的热部署

程序员文章站 2022-03-02 22:40:44
...

@

实现类的热部署

jvm在加载类之前会检查请求的类是否已经被加载过来,也就是要调用覅你的LoadedClass()方法查看是否能返回类的实例。如果类已经加载过来,再调用loadedClass()将会导致冲突。
实现类的热部可以创建不同的ClassLoader实例对象,然后通过这个不同的实例对象来加载同名的类。

方法1:重写findClass类

package excersize1;

import java.io.;
import java.lang.reflect.Method;
import java.util.
;

public class ClassReloader extends ClassLoader{

private String classPath;
String classname="excersize1.Cifa";

public ClassReloader(String classPath) {
	this.classPath=classPath;
	
}

public Class<?> findClass(String name) throws ClassNotFoundException {
	byte[] classData=getData(name);
	if(classData==null) {
		
		throw new ClassNotFoundException();
		
	}else {
		return defineClass(classname,classData,0,classData.length);
		
	}
}

	
private byte[] getData(String name) {
	// TODO Auto-generated method stub
	//String fileName=getFileName(className);
	 StringBuffer sb = new StringBuffer(classPath); 
        String classname = name.replace('.', File.separatorChar) + ".class";
        StringBuffer path=  sb.append(File.separator + classname); 
	//String path=classPath+className;
	try {
	InputStream is=new FileInputStream(path.toString());
	ByteArrayOutputStream stream=new ByteArrayOutputStream();
	byte[] buffer=new byte[2048];
	int num=0;
	while((num=is.read(buffer))!=-1) {
		stream.write(buffer,0,num);
	}
		return stream.toByteArray();
	}catch(IOException e) {
		
		e.printStackTrace();
	}
	return null;
}


public static void main(String [] args) {
	
	Timer timer=new Timer();
	timer.schedule(new TimerTask(){
	@Override
	public void run() {
		try { 
	
		String path="E:\\深入分析\\excersize1\\bin";
		ClassReloader reloader=new ClassReloader(path);
		Class r=reloader.findClass("excersize1.Cifa");
		Object foo = r.newInstance(); 
		 Method m = foo.getClass().getMethod("say"); 
		 m.invoke(foo, new Object[]{}); 
		
		//System.out.println(r.newInstance());
		 
		 /*
		ClassReloader reloader2=new ClassReloader(path);
		Class r2=reloader2.findClass("excersize1.Cifa");
		System.out.println(r2.newInstance());
		*/
		 }  catch(Exception ex) { 
		        ex.printStackTrace(); 
		    } 
		}
		}, 0,1000);
		}
}

Cifa类如下

package excersize1;

public class Cifa {
public void say(){
System.out.println(“Say Hello”);
}
}

方法1:重写loadClass类

package excersize2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;

class CustomCL extends ClassLoader {

private String basedir; // 需要该类加载器直接加载的类文件的基目录
private HashSet dynaclazns; // 需要由该类加载器直接加载的类名

public CustomCL(String basedir, String clazns) throws FileNotFoundException, IOException { 
    super(null); // 指定父类加载器为 null 
    this.basedir = basedir; 
    dynaclazns = new HashSet(); 
    loadClassByMe(clazns); 
} 

private void loadClassByMe(String clazns) throws FileNotFoundException, IOException { 
    //for (int i = 0; i < clazns.length; i++) { 
        loadDirectly(clazns); 
        dynaclazns.add(clazns); 
   // } 
} 

private Class loadDirectly(String name) throws FileNotFoundException, IOException { 
    Class cls = null; 
    StringBuffer sb = new StringBuffer(basedir); 
    String classname = name.replace('.', File.separatorChar) + ".class";
    sb.append(File.separator + classname); 
    File classF = new File(sb.toString()); 
    cls = instantiateClass(name,new FileInputStream(classF),
        classF.length()); 
    return cls; 
}           

private Class instantiateClass(String name,InputStream fin,long len) throws IOException{ 
    byte[] raw = new byte[(int) len]; 
    fin.read(raw); 
    fin.close(); 
    return defineClass(name,raw,0,raw.length); 
} 
 
protected Class loadClass(String name, boolean resolve) 
        throws ClassNotFoundException { 
    Class cls = null; 
    cls = findLoadedClass(name); 
    if(!this.dynaclazns.contains(name) && cls == null) 
        cls = getSystemClassLoader().loadClass(name); 
    if (cls == null) 
        throw new ClassNotFoundException(name); 
    if (resolve) 
        resolveClass(cls); 
    return cls; 
} 

}

Test程序如下

package excersize2;

import java.lang.reflect.Method;
import java.util.;
import java.util.
;

public class Test {

public static void main(String []args){
	Timer timer=new Timer();
	timer.schedule(new TimerTask(){
	@Override
	public void run() {
		try { 
	        // 每次都创建出一个新的类加载器
			ClassLoader c = Test.class.getClassLoader();
			//ClassLoader;
			//ClassLoader c=new ClassLoader("E:\\深入分析\\excersize2\\bin", new String[]{"excersize2.Foo"});
	        
			
			
			CustomCL cl = new CustomCL("E:\\深入分析\\excersize2\\bin", "excersize2.Foo"); 
	        Class cls = cl.loadClass("excersize2.Foo"); 
	        Object foo = cls.newInstance(); 
	 
	        Method m = foo.getClass().getMethod("sayHello", new Class[]{}); 
	        m.invoke(foo, new Object[]{}); 
	        
	        
			
			
			/*
			 Class cls = c.loadClass("excersize2.Foo"); 
		        Object foo = cls.newInstance(); 
		 
		        Method m = foo.getClass().getMethod("sayHello", new Class[]{}); 
		        m.invoke(foo, new Object[]{}); 
		        
		        */
	     
	    }  catch(Exception ex) { 
	        ex.printStackTrace(); 
	    } 
	}
	}, 0,1000);
	}

}

相关标签: javaweb