一、类加载
1.类加载过程模拟(先明白类加载过程,方可模拟类运行期间加载-创建代理类,调用目标方法)
public class Programmer {
public void code() {
System.out.println("I'm a Programmer,Just Coding.....");
}
}
/**
* 自定义一个类加载器,用于将字节码转换为class对象
*/
public class MyClassLoader extends ClassLoader {
public Class<?> defineMyClass(byte[] b, int off, int len) {
//TODO SOURCE CODE
return super.defineClass(null,b, off, len);
}
}
public class MyTest {
public static void main(String[] args) throws IOException {
//读取本地的class文件内的字节码,转换成字节码数组
File file = new File(".");
InputStream input = new FileInputStream(file.getCanonicalPath() +
"\\target\\classes\\com\\max\\dproxy\\loadseq\\Programmer.class");
byte[] result = new byte[1024];//字节型
int count = input.read(result);
// 使用自定义的类加载器将 byte字节码数组转换为对应的class对象
MyClassLoader loader = new MyClassLoader();
Class clazz = loader.defineMyClass(result, 0, count);
//测试加载是否成功,打印class 对象的名称
System.out.println(clazz.getCanonicalName());
try {
//实例化一个Programmer对象
Object o = clazz.newInstance();
//调用Programmer的code方法
clazz.getMethod("code", null).invoke(o, null);
} catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
2.类加载过程
注:绿色椭圆内即JVM虚拟机状态,具体不做赘述。
二、动态代理
代理模式:
静态代理:手动编写代理类代理目标类方法。缺点:手动创建;代理类越来越多,系统规模增大,不易维护;
动态代理:由于JVM通过字节码的二进制(byte-code)信息加载类的,那么,如果我们在运行期系统中,1.遵循Java编译系统组织.class文件的格式和结构,2.生成相应的二进制数据,3.然后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中,动态创建一个类的能力了。
JDK实现动态代理
public interface Vehicle {
void drive();
}