静态代理
编译阶段就生产了对应的代理类
public interface IBussiness { void execute(); }
public class BussinessImpl implements IBussiness{ @Override public void execute() { System.out.println("执行业务逻辑..."); } }
public class BussinessProxy implements IBussiness{ private IBussiness bussinessImpl; public BussinessProxy(IBussiness bussinessImpl) { this.bussinessImpl = bussinessImpl; } @Override public void execute() { System.out.println("前拦截..."); bussinessImpl.execute(); System.out.println("后拦截..."); } }
public class Test { public static void main(String[] args) { IBussiness bussiness = new BussinessImpl(); BussinessProxy proxy = new BussinessProxy(bussiness); proxy.execute(); } }
JDK动态代理
动态生成字节码,加载到内存中,利用反射去执行真正的方法
关键代码:
Proxy.newProxyInstance(ClassLoader, Interfaces, InvocationHandler);
生成代理类时,要将类加载器,接口和InvocationHandler传递过去,
类加载器的作用是,生成的字节码要加载到JVM当中
接口的作用是,生成的代理类要知道代理的有哪些方法
InvocationHandler的作用是,在代理类中实际执行的是InvocationHandler的invoke方法
public interface Person { /** * 唱歌 */ void sing(); /** * 跳舞 * @param name 舞曲名 * @return */ String dance(String name); }
public class PersonImpl implements Person{ @Override public void sing() { System.out.println("开始唱歌"); } @Override public String dance(String name) { System.out.println("跳" + name); return "不好玩"; } }
public class PersonImplProxy { private Person person = new PersonImpl(); /** * 创建代理 * @return 返回值是接口类型 */ public Person createProxy() { /** * 产生某个对象的代理对象 * ClassLoader loader 当前代理对象的类加载器 * Class<?>[] interfaces 代理对象的接口 * InvocationHandler h InvocationHandler对象 */ return (Person) Proxy.newProxyInstance(PersonImplProxy.class.getClassLoader(), person.getClass().getInterfaces(), new InvocationHandler() { /** * @param proxy 把代理对象自身传进去 * @param method 代表当前调用的方法 * @param args 当前调用方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 获取方法名 String methodName = method.getName(); if ("sing".equals(methodName)) { System.out.println(); System.out.println("前置通知... 唱歌开始"); method.invoke(person, args); System.out.println("后置通知... 唱歌结束"); } else if ("dance".equals(methodName)) { System.out.println(); System.out.println("前置通知 ... 跳舞开始"); Object res = method.invoke(person, args); System.out.println("后置通知 ... 跳舞结束"); return res; } return null; } }); } }
public class Test { public static void main(String[] args) { //设置为true后,可以保存生成的代理类的字节码, //注意字节码文件用jd-gui.exe打开,用javap打开显示不全,javap是JDK自带的工具,他们之间的具体实现是不一样的 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); PersonImplProxy proxy = new PersonImplProxy(); Person person = proxy.createProxy(); person.sing(); System.out.println(person.dance("华尔兹三章")); System.out.println(); System.out.println("生成的代理类的名称: " + person.getClass().getName()); } }
测试结果
生成字节码文件
将字节码文件反编译后
public final class $Proxy0 extends Proxy implements Person { private static Method m1; private static Method m2; private static Method m3; private static Method m4; private static Method m0; public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } public final boolean equals(Object paramObject) { try { return ((Boolean) this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String) this.h.invoke(this, m2, null); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void sing() { try { this.h.invoke(this, m3, null); return; } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String dance(String paramString) { try { return (String) this.h.invoke(this, m4, new Object[] { paramString }); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer) this.h.invoke(this, m0, null)).intValue(); } catch (Error | RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m3 = Class.forName("com.irish.deligate.Person").getMethod("sing", new Class[0]); m4 = Class.forName("com.irish.deligate.Person").getMethod("dance", new Class[] { Class.forName("java.lang.String") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }
可以看到代理类继承了Proxy,实现了我们传递的接口,当调用dance方法时,会转调InvocationHandler的invoke方法,将方法和参数传递过去,由invoke来具体执行代理的逻辑,InvocationHandler持有真正的对象,一般是在调用真正的对象方法前后,执行我们要进行增强的操作。