与动态相对的是静态,静态代理是在代码编译时生成的。动态代理的动态是指在程序运行期生成的代理对象。
接口
public interface OutInfo { void printInfo(); }实现类
public class Person implements OutInfo { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } @Override public void printInfo() { System.out.println(name + "..." + age); } }动态代理类最终底层调用的方法实现InvocationHandler
public class personHandler implements InvocationHandler { private Object obj; public personHandler (Object obj) { this.obj = obj; } /** * proxy:代表动态代理对象 * method:代表正在执行的方法 * args:代表调用目标方法时传入的实参 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.print("进入了代理\n"); Object result = method.invoke(obj, args); System.out.print("时间为:" + new Date() + "\n\n"); return result; } }生成动态代理类
public class DynamicProxy { public static void main(String[] args) { Person person = new Person("张三", 23); OutInfo outInfoProxy = (OutInfo ) Proxy .newProxyInstance(person.getClass().getClassLoader(), person .getClass().getInterfaces(), invocationHandler); } outInfoProxy.printInfo(); }Proxy.newProxyInstance()方法产生了最终的代理对象 P r o x y , Proxy, Proxy,Proxy字节码反编译后的文件如下:
选取了比较重要的代码: public final class $Proxy extends Proxy implements OutInfo { private static Method m1; private static Method m3; private static Method m2; private static Method m0; public $Proxy(InvocationHandler var1) throws { super(var1); } public final void printInfo() throws { try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } }所以最后代理对象$Proxy调用OutInfo 接口的printInfo()方法最后是调用了 super.h.invoke(this, m3, (Object[])null);
这个h就是 Proxy.newProxyInstance(person.getClass().getClassLoader(), person .getClass().getInterfaces(), invocationHandler); 传入的invocationHandler,看到最后就是调用到了invocationHandler的invoke。
invoke(this, m3, (Object[])null) invoke(Object proxy, Method method, Object[] args)
还是最终生成的动态代理类 $Proxy extends Proxy implements OutInfo 继承了Proxy 类,实现了OutInfo接口,所以java中不能多重继承,当动态代理类实现了jdk中的Proxy.class类的时候,就只能通过实现目标接口的方式来实现拓展。 所以jdk的代理一定是基于接口实现