先上代码,怎么使用jdk的动态代理。
定义一个接口,UserService,里面有add方法
定义一个类实现UserService
测试类
public interface UserService {
void add();
}
===========
public class UserServImp implements UserService {
@Override
public void add() {
System.out.println("add");
}
}
========
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test2 {
public static void main(String[] args) {
UserService serv = new UserServImp();
UserService servProxy = (UserService) Proxy.newProxyInstance(serv.getClass().getClassLoader(), serv.getClass().getInterfaces(), new InvocationHandler() {
@Override //参数解释 proxy 真实的那个代理对象 method方法对象 args 方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------");
return method.invoke(serv, args);
}
});
servProxy.add();
}
}
最后执行结果如下

接下来简单说说原理,
当我们调用代理类的方法的时候,代理类会把自己(反编译源代码发现),方法,参数 传递给 handler ,handler 会执行invoke方法。
所以当我们每调用一次代理的方法,都会走handler
细心的朋友可能会发现 原始类和代理类的hashcode一致,如下图所示

之所以相等是因为都是调用原来的对象的hashcode方法,但其实是不同的对象哈。
注意:
默认jdk不会把代理类字节码生成到本地文件系统
需要配置 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
然后可以在你的项目comsunproxy 目录找到到该代理类的字节码 (jdk8会自动创建目录,jdk7好像不会 需要手动创建该目录)
使用反编译(eg:jd-gui)即可查看
原理解说看这里 jdk动态代理原理