java 自定义classloader_自定义ClassLoader

由于ClassLoader的单亲委托结构,保证了JVM中加载的类的安全性。BootstrapClassloader会加载java核心库(例如:java.lang.*等);ExtClassloader会加载jdk安装目录下的ext目录下的jar包(即jdk1.6.0_18\jre\lib\ext),包括dnsns.jar、sunjce_provider.jar...等;AppClassloader会加载当前目录(即'.')和classpath中内容。在加载的过程中,会尽量尝试用父亲去加载,父亲如果不加载,才尝试子Classloader加载。

自定义Classloader具有相当的实际意义,例如在同一环境下需要多个同一字节码的多个Class模型(Jboss容器中多个应用使用同一类,但彼此隔离,完全没有关系)。

查看java的源代码,java中的调用关系如下:ClassLoader类的loadClass(String name) -》loadClass(String name, boolean resolve) [会先尝试父亲加载,父亲不加载才ClassLoader加载]-》findClass(String name),而此方法的实现为空,因此自定义的Classloader需要复写findClass(String name)。

packageorg.apache.jmeter.loader;

importjava.io.ByteArrayOutputStream;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.IOException;

importjava.nio.ByteBuffer;

importjava.nio.channels.Channels;

importjava.nio.channels.FileChannel;

importjava.nio.channels.WritableByteChannel;

/**

* TODO Comment of JmeterClassLoader

*

* @author keju.wangkj

*/

publicclassJmeterClassLoaderextendsClassLoader {

privatestaticfinalString SUFFIX  =".class";

privateString              baseDir = System.getProperty("user.dir");

publicJmeterClassLoader() {

super();

}

publicJmeterClassLoader(String baseDir) {

this.baseDir = baseDir;

}

publicJmeterClassLoader(ClassLoader parent, String baseDir) {

super(parent);

this.baseDir = baseDir;

}

publicClass> findClass(String className)throwsClassNotFoundException {

Class> clazz = this.findLoadedClass(className);

if(null== clazz) {

try{

String classFile = getClassFile(className);

FileInputStream fis = newFileInputStream(classFile);

FileChannel fileC = fis.getChannel();

ByteArrayOutputStream baos = newByteArrayOutputStream();

WritableByteChannel outC = Channels.newChannel(baos);

ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

while(true) {

inti = fileC.read(buffer);

if(i ==0|| i == -1) {

break;

}

buffer.flip();

outC.write(buffer);

buffer.clear();

}

fis.close();

byte[] bytes = baos.toByteArray();

clazz = defineClass(className, bytes, 0, bytes.length);

} catch(FileNotFoundException e) {

e.printStackTrace();

} catch(IOException e) {

e.printStackTrace();

}

}

returnclazz;

}

privateString getClassFile(String name) {

StringBuffer sb = newStringBuffer(baseDir);

name = name.replace('.', File.separatorChar) + SUFFIX;

sb.append(File.separator + name);

returnsb.toString();

}

/*

* (non-Javadoc)

* @see java.lang.Object#toString()

*/

@Override

publicString toString() {

returnthis.getClass().getName();

}

}

其中的findClass()将被classloader类中loadclass方法所调用,所以使用时可以直接调用loadclass方法即可,此为模板方法模式的典型使用。

2、卸载问题

loader1 = null;

clazz = null;

object = null;

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页