1、自定义类加载器
package com.ln.concurrent.classloader.chapter3;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.classloader.chapter3
* @Name:MyClassLoader
* @Author:linianest
* @CreateTime:2021/1/6 15:27
* @version:1.0
* @Description TODO: 自定义类加载器
*/
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 1、继承累加器器
*/
public class MyClassLoader extends ClassLoader {
// 默认的加载路径
private static final String DEFULT_DIR = "E://";
private String dir = DEFULT_DIR;
private String classLoaderName;
public MyClassLoader() {
super();
}
public MyClassLoader(String classLoaderName) {
super();
this.classLoaderName = classLoaderName;
}
// 指定该类加载器的父亲是哪个
public MyClassLoader(String classLoaderName, ClassLoader parent) {
super(parent);
this.classLoaderName = classLoaderName;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
/**
* 返回找的class文件字节数组
*
* @param name
* @return
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
final String classpath = name.replace(".", "/");
final File classfile = new File(dir, classpath + ".class");
if (!classfile.exists()) {
throw new ClassNotFoundException("The class " + name + " not found under directory [" + dir + "]");
}
// 将文件读取到字节数组中
byte[] classBytes = loadClassBytes(classfile);
if (null == classBytes || classBytes.length == 0) {
throw new ClassNotFoundException("load the class " + name + " failed");
}
return this.defineClass(name, classBytes, 0, classBytes.length);
}
/**
* 将文件读取到内存字节数组并加密后,输出流中
*
* @param classfile
* @return
*/
private byte[] loadClassBytes(File classfile) {
try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final FileInputStream fileInputStream = new FileInputStream(classfile);) {
final byte[] buffer = new byte[1024];
int len;
// 将读取的数据流到缓冲区中并输出
while ((len = fileInputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
测试:使用反射的方式
package com.ln.concurrent.classloader.chapter3;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ProjectName: java-concurrency
* @Package: com.ln.concurrent.classloader.chapter3
* @Name:MyClassLoaderTest
* @Author:linianest
* @CreateTime:2021/1/6 15:43
* @version:1.0
* @Description TODO: 测试
*/
public class MyClassLoaderTest {
public String hello(){
return "hello word.";
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
final MyClassLoader myclassload = new MyClassLoader("myclassload");
final Class<?> loadClass = myclassload.loadClass("com.ln.concurrent.classloader.chapter3.MyClassLoaderTest");
System.out.println(loadClass);
System.out.println(loadClass.getClassLoader());
final Object obj = loadClass.newInstance();
// 指定方法名称以及返回值类型
final Method method = loadClass.getMethod("hello", new Class<?>[]{});
final Object result = method.invoke(obj, new Object[]{});
System.out.println(result);
}
}