实现类的热部署

@

实现类的热部署

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);
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值