动态代理,可以对接口、类进行代理,其中jdk自带的动态代理,只能通过接口代理,其他如:asm、cglib、javaassist对两者均可代理,其中保存jdk动态类方法:
package demo; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Properties; /** * @author yeyong */ public class ProxyTest2 { public static void main(String[] args) throws Exception { // 添加以下的几段代码, 就可以将代理生成的字节码保存起来了 Field field = System.class.getDeclaredField("props"); field.setAccessible(true); Properties props = (Properties) field.get(null); props.put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); Package pkg = ProxyTest2.class.getPackage(); if (pkg != null) { String packagePath = pkg.getName().replace(".", File.pathSeparator); new File(packagePath).mkdirs(); } IA a = new IAImpl(); InvocationHandlerImpl ih = new InvocationHandlerImpl(a); IA proxyA = (IA) Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), ih); proxyA.a(); } } interface IA { void a(); int b(String str); } class IAImpl implements IA { @Override public void a() { System.out.println("IAImpl.a()"); } @Override public int b(String str) { System.out.println("IAImpl.b()"); return 0; } } class InvocationHandlerImpl implements InvocationHandler { private Object target; public InvocationHandlerImpl(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before..."); Object res = method.invoke(target, args); System.out.println("after..."); return res; } }
反编译后源码如下
package demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class $Proxy0 extends Proxy implements IA { private static Method m1; private static Method m4; private static Method m3; private static Method m0; private static Method m2; 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 (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int b(String paramString) { try { return ((Integer) this.h.invoke(this, m4, new Object[] { paramString })).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void a() { try { this.h.invoke(this, m3, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer) this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String) this.h.invoke(this, m2, null); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m4 = Class.forName("demo.IA").getMethod("b", new Class[] { Class.forName("java.lang.String") }); m3 = Class.forName("demo.IA").getMethod("a", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }