java类加载流程
java jvm系统自带三个类加载
- BootStrap ClassLoader
最顶层的类加载器,主要加载核心类库,JRE_HOME\lib下的rt.jar、resources.jar、charsets.jar等类。 - Extention ClassLoader 扩展类加载器,主要加载JRE_HOME\lib\ext目录下的jar包类
- Appclass Loader 应用类加载器,主要加载所有应用classpath目录下的所有类
双亲委派
一个类加载器查找class和resource时,是通过委托模式进行的,它首先判断这个class是否已经加载成功,如果没有的话它并不是先自已进行查找,而是先通过父类加载器查找加载,找不到就递归父加载器,直到Bootstrap ClassLoader,如果BootStrap classLoader找不到,则一级一级的返回,最后到达自身去查找这些对象。
通过ClassLoader加密class文件
- 需要加密的类
package com.zhanghf.classloader;
import java.util.Date;
public class ClassLoaderAttach extends Date {
@Override
public String toString() {
return "this is ClassLoaderAttach";
}
}
- 对class文件加解密
package com.zhanghf.classloader;
import java.io.*;
/**
* 对class加密
* 把1变为0,把0变为1
*/
public class ClassEncryptHelper {
public static void main(String[] args) throws IOException {
String srcPath = args[0];
String destDir = args[1];
String destFileName = srcPath.substring(srcPath.lastIndexOf("\\") + 1);
String destFilePath = destDir + "\\" + destFileName;
FileInputStream fin = new FileInputStream(srcPath);
FileOutputStream fout = new FileOutputStream(destFilePath);
cypher(fin, fout);
fin.close();
fout.close();
}
/**
* <p>Title: cypher</p>
* <p>Description:加密、解密, 将原来的1改为0,0改为1</p>
*
* @param in
* @param out
* @throws IOException
*/
public static void cypher(InputStream in, OutputStream out) throws IOException {
int b = 0;
while ((b = in.read()) != -1) {
out.write(b ^ 0xff);
}
}
}
- 编写自已的classload类
package com.zhanghf.classloader;
import java.io.*;
public class MyClassLoader extends ClassLoader{
private String classDir;
public MyClassLoader(){
}
public MyClassLoader(String classDir){
this.classDir=classDir;
}
/**
* 覆盖ClassLoader的findClass方法
*/
@Override
protected Class<?> findClass(String name)
throws ClassNotFoundException {
String classFileName = classDir + "\\" + name + ".class";
try {
FileInputStream fin = new FileInputStream(classFileName);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
//解密
ClassEncryptHelper.cypher(fin,baout);
fin.close();
//转为字节数组
byte[] byteArray = baout.toByteArray();
return defineClass(byteArray, 0, byteArray.length);
} catch (Exception e) {
}
return null;
}
}
- 测试类
package com.zhanghf.classloader;
import java.util.Date;
public class MyClassLoadTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// ClassLoaderAttach classLoaderAttach = new ClassLoaderAttach();
// System.out.println(classLoaderAttach.toString());
Class<?> c = new MyClassLoader("D:").loadClass("ClassLoaderAttach");
Date d = (Date) c.newInstance();
System.out.println(d);
}
}
网友评论