实现类的热部署
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);
}
}