ClassLoader的基础知识,类加载相关的知识问度娘,这里仅展示如何自定义ClassLoader实现类加载
public class MyClassLoader extends ClassLoader {
//文件加载目录
private final static String DEFAULT_DIR = "G:\\classloader1";
private String dir = DEFAULT_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;
}
/**
* xxx.xxx.xxx.xxx.AAA
* xxx/xxx/xxx/xxx/AAA.class
*
* @param name 全类名
* @return
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String name)
throws ClassNotFoundException {
String classPath = name.replace(".", "/");
File classFile = new File(dir, classPath + ".class");
if (!classFile.exists()) {
throw new ClassNotFoundException("The class " + name + " not found under " + 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);
}
/**
* 把文件读出来 转化成字节数组
*/
private byte[] loadClassBytes(File classFile) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(classFile)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public String getClassLoaderName() {
return classLoaderName;
}
}
public class MyClassLoaderTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
MyClassLoader classLoader = new MyClassLoader("MyClassLoader");
Class<?> aClass = classLoader.loadClass("com.shs.concurrent.classloader.chapter3.MyObject");
System.out.println(aClass);
System.out.println(aClass.getClassLoader());
System.out.println(classLoader.getClass().getClassLoader());
Object obj = aClass.newInstance();
Method method = aClass.getMethod("hello", new Class<?>[]{});
Object result = method.invoke(obj, new Object[]{});
System.out.println(result);
}
}
通过自定义加密解密的ClassLoader,对类实行保护
public final class EncryptUtils {
public static final byte ENCRYPT_FACTOR = (byte) 0xff;
private EncryptUtils() {
//empty
}
/**
* 加密方法
* @param source 源文件
* @param target 目标文件
*/
public static void doEncrypt(String source, String target) {
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(target)) {
int data;
while ((data = fis.read()) != -1) {
fos.write(data ^ ENCRYPT_FACTOR);
}
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//对class文件加密处理
doEncrypt("G:\\classloader3\\com\\shs\\concurrent\\classloader\\chapter3\\MyObject.class", "G:\\classloader3\\com\\shs\\concurrent\\classloader\\chapter3\\MyObject.class1");
}
}
/**
* 自定义解密加载器 对class解密
*/
public class DecryptClassLoader extends ClassLoader {
private final static String DEFAULT_DIR = "G:\\Teaching\\app\\classloader3";
private String dir = DEFAULT_DIR;
public DecryptClassLoader() {
super();
}
public DecryptClassLoader(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> findClass(String name)
throws ClassNotFoundException {
String classPath = name.replace(".", "/");
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);
}
private byte[] loadClassBytes(File classFile) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(classFile)) {
int data;
while ((data = fis.read()) != -1) {
baos.write(data ^ EncryptUtils.ENCRYPT_FACTOR);
}
baos.flush();
return baos.toByteArray();
} catch (IOException e) {
return null;
}
}
public void setDir(String dir) {
this.dir = dir;
}
}
//=================================
public class ClassLoaderTest {
public static void main(String[] args) throws Exception {
//只有这个解密加载器才能正常加载该类
DecryptClassLoader classLoader = new DecryptClassLoader();
Class<?> aClass = classLoader.loadClass("com.shs.concurrent.classloader.chapter3.MyObject");
System.out.println(aClass);
Object obj = aClass.newInstance();
Method method = aClass.getMethod("hello", new Class<?>[]{});
Object result = method.invoke(obj, new Object[]{});
System.out.println(result);
}
}
其他加载器会因为模数因子检验而加载失败