#对于动态代理之前一直对它不是很清楚,没有清晰的认识,静态重新梳理了一下~
#动态代理中是通过 newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)来创建实例对象的,该方法的 参数的解析如下。
第一个参数:类加载器
* 在实例化对象时,需要调用类的构造函数,在运行期间调用构造函数时,就会引起类加载,
* 加载类:JVM拿着ClassLoader去加载类的字节码,将字节码存储在内存中,才能去实例化对象。
Class[] 需要进行实例化对象,实例化对象即实例化某个类的对象,所以到底是那个类呢?
* 类在哪里,字节码在哪里?
* 这个类并不存在硬盘上,存在内存中,由动态代理在内存中“动态生成”的
* 一个类实现某个接口,
第三个参数:InvocationHandler
* 通代理对象所在的类,实现某个接口,代理对象就有了接口中的所有方法。 可以通过代理对象去 调用 add等方法。
* * 注意:每次代理对象调用方法时,不会进入到 真正的add()方法中,进入的是 实现了InvocationHandler接口中的invoke()方法中。
定义一个接口
public interface Calculate {
public int add(int a, int b);
public int div(int a, int b);
}
`
定义一个接口的实现类
class Cal implements Calculate {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int div(int a, int b) {
return a / b;
}
定义实现了InvocationHandler接口的类
* 通过构造方法,将要代理的对象传入
class Myhandler implements InvocationHandler {
//要代理的对象
Object target = new Object();
public Myhandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("add".equals(method.getName())) {
System.out.println("日志开始");
Object t = method.invoke(target, args);
System.out.println(t);
System.out.println("日志结束");
}
return 0;
}
}
产生代理对象
public static void main(String[] args) {
ClassLoader cl = AppTest.class.getClassLoader();
//目标对象
Calculate cal = new Cal();
Calculate calculate = (Calculate) Proxy.newProxyInstance(cl, new Class[]{Calculate.class}, new Myhandler(cal));
calculate.add(1, 2);
}