先看下DEMO中用到的类。注意看类中的注释。
接口类
public interface IMyDao {
public String query();
public void delete();
}
目标类(实现接口的类)
/**
* MyDao 目标类
**/
public class MyDao implements IMyDao {
@Override
public String query() {
System.out.println("------jdk dynamic proxy...querying......");
return "query_result";
}
@Override
public void delete() {
System.out.println("------jdk dynamic proxy...deleting......");
}
}
切面/代理逻辑类(InvocationHandler类)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class CustomInvocationHandler implements InvocationHandler {
private Object object;
public CustomInvocationHandler(Object obj){
this.object = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------before----call target method........"); // 代理类的业务逻辑
Object invoke = method.invoke(object, args); // 执行目标对象的方法
System.out.println("------after-----call target method........"); // 代理类的业务逻辑
return invoke;
}
}
Main类
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
/*
* newProxyInstance干了什么? 猜测,
* 1. 拼接代理类的源码
* 2. 把代理类源码输出到*.java 文件($Proxy.java)
* 3. 动态编译源码文件为$Proxy.class 字节码
* 4. 通过类加载器把代理类加到到JVM中
* 5. 通过Class.forName("*").newInstance 反射实例化这个对象
*
* 实际:
* JDK直接在内存中生成字节码
*
**/
IMyDao myDaoProxy = (IMyDao) Proxy.newProxyInstance(Main.class.getClassLoader(),
new Class[]{IMyDao.class}, // 生成一个实现该接口的代理类,并继承Proxy类。在代理类中重写接口中的每个方法
new CustomInvocationHandler(new MyDao())); // 为代理类传入我们的切面/代理逻辑类(InvocationHandler)
/*
* 最终效果:
* 当调用这个代理对象某个方法时,本质是调用了前面传入的CustomInvocationHandler的invoke方法。
**/
myDaoProxy.query();
myDaoProxy.delete();
}
}
执行效果:
如有问题,有疑惑欢迎留言,私信一起探讨~