某个类如何想要采用jdk的动态代理,这个类必须要实现一个接口。
JDK的动态代理有几个关键的类和接口:
(1) Proxy: 用来生产代理对象与代理类(com.sun.proxy.$ProxyN)
生产的代理类就是:
com.sun.proxy.$ProxyN
N是从0开始的整数
(2) InvocationHandler:回调处理程序,当代理对象调用某个方法时,就会调用这个接口中的invoke方法
-
被代理接口
package my.annotation.learn;public interface ServiceInf { public void fun01(); public void fun02(); }
-
被代理的目标类
package my.annotation.learn;public class TargetClass implements ServiceInf{ @Override public void fun01() { System.out.println("TargetClass->fun01()"); } @Override public void fun02() { System.out.println("TargetClass->fun02()"); } }
-
回调处理程序
InvocationHandler调用处理程序是一个与代理对象绑定的对象,当在一个代理对象上调用被代理方法时都会调用InvocationHandler实现类的实例上的invoke方法
package my.annotation.learn;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** InvocationHandler是代理对象的调用处理器要实现的接口 每一个代理对象都有一个相关联的调用处理器 当在一个代理对象上调用某个方法时,该方法的调用都会被编码和发送到这个方法的调用处理程序上 */ public class MyInvocationHandler implements InvocationHandler{ private TargetClass target; public MyInvocationHandler(TargetClass target) { this.target = target; } /** * proxy jdk生产的代理对象 * method 要调用的接口的方法的实例 * args 调用方法传递的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理方法开始执行"); System.out.println(proxy.getClass().getName()); System.out.println(method); method.invoke(target, args); System.out.println("代理方法开始结束"); return null; } }
4.运行代码
package my.annotation.learn;
import java.lang.reflect.Proxy;
public class Demo {
public static void main(String[] args) {
TargetClass target=new TargetClass();
ServiceInf proxy =(ServiceInf) Proxy.newProxyInstance(Demo.class.getClassLoader(),
new Class<?>[] {ServiceInf.class}, new MyInvocationHandler(target));
proxy.fun01();
}
}
运行结果如下:
代理方法开始执行
com.sun.proxy.$Proxy0
public abstract void my.annotation.learn.ServiceInf.fun01()
TargetClass->fun01()
代理方法开始结束
从运行结果中我们可以看到 proxy是生产的代理对象,method是接口中的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable