先说结论:
1,动态代理,继承Proxy,类实现接口。但需要反射。动态代理类,会被缓存。但反射仍慢。
2,100M次性能结果:
testDynamicProxyPerformance=73277 //先newInstance(),再方法的反射调用。
testDynamicProxyFilePerformance=1639 //没有newInstance(),只有方法的反射调用。
testStaticProxyPerformance=38
过程:
1,接口。
package time.river.proxy; public interface ITarget{ public void doA(int age); public void doB(String name, int age); public int getAge(); public void setAge(int age); }
2,目标类
package time.river.proxy; public class MyTarget implements ITarget { private int age; @Override public void doA(int age) { System.out.println("doA.....,age=" + age); } @Override public void doB(String name, int age) { System.out.println("doB.....,name=" + name + ",age=" + age); } @Override public int getAge() { return age; } @Override public void setAge(int age) { this.age = age; } }
3,Handler
package time.river.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyHandler implements InvocationHandler { private Object targetObj; public MyHandler(Object targetObj) { this.targetObj = targetObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // System.out.println("哥是代理------------------------------------"); return method.invoke(targetObj, args); } }
4, 测试类
package time.river.proxy; import java.io.FileOutputStream; import java.lang.reflect.Proxy; import sun.misc.ProxyGenerator; public class Test { public static void main(String args[]) throws Exception{ // testDynamicProxy(); // createProxyClassFile(); // testProxyFile(); testDynamicProxyPerformance(); testDynamicProxyFilePerformance(); testStaticProxyPerformance(); } private static void testDynamicProxy() throws Exception{ MyTarget target = new MyTarget(); ITarget proxy = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class[] { ITarget.class }, new MyHandler(target)); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } /** * 生成的动态代理文件。使用jad反编译。 */ private static void createProxyClassFile() throws Exception{ String name = "DynamicProxy"; //生成的动态代理文件。 //Proxy内部方法:ProxyGenerator.generateProxyClass。 byte[] data = ProxyGenerator.generateProxyClass(name, new Class[] { ITarget.class }); FileOutputStream out = new FileOutputStream(name + ".class"); out.write(data); out.close(); } public static void testProxyFile(){ MyTarget target = new MyTarget(); MyHandler handler = new MyHandler(target); DynamicProxy proxy = new DynamicProxy(handler); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } private static int cnt = 1000 * 1000 * 100; private static void testDynamicProxyPerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testDynamicProxy(); } long e = System.currentTimeMillis(); System.out.println("testDynamicProxyPerformance="+(e-s)); } private static void testDynamicProxyFilePerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testProxyFile(); } long e = System.currentTimeMillis(); System.out.println("testDynamicProxyFilePerformance="+(e-s)); } private static void testStaticProxyPerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testStaticProxy(); } long e = System.currentTimeMillis(); System.out.println("testStaticProxyPerformance="+(e-s)); } public static void testStaticProxy(){ MyTarget target = new MyTarget(); StaticProxy proxy = new StaticProxy(target); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } }
5,动态代理类。保存到class文件,再用jad反编译。
package time.river.proxy; import java.lang.reflect.*; import time.river.proxy.ITarget; /** * Test类createProxyClassFile()方法,生成的class文件。然后用jad反编译,再修改语法错误。 */ public final class DynamicProxy extends Proxy implements ITarget { public DynamicProxy(InvocationHandler invocationhandler) { super(invocationhandler); } public final void setAge(int i) { try { super.h.invoke(this, m6, new Object[] { Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })).booleanValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return false; } public final void doA(int i) { try { super.h.invoke(this, m3, new Object[] { Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int getAge() { try { return ((Integer) super.h.invoke(this, m5, null)).intValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return 0; } public final void doB(String s, int i) { try { super.h.invoke(this, m4, new Object[] { s, Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return 0; } public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return ""; } private static Method m6; private static Method m1; private static Method m3; private static Method m5; private static Method m4; private static Method m0; private static Method m2; static { try { m6 = Class.forName("time.river.proxy.ITarget").getMethod("setAge", new Class[] { Integer.TYPE }); m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m3 = Class.forName("time.river.proxy.ITarget").getMethod("doA", new Class[] { Integer.TYPE }); m5 = Class.forName("time.river.proxy.ITarget").getMethod("getAge", new Class[0]); m4 = Class.forName("time.river.proxy.ITarget").getMethod("doB", new Class[] { Class.forName("java.lang.String"), Integer.TYPE }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } }
6,静态代理类
package time.river.proxy; public class StaticProxy implements ITarget{ private ITarget target; public StaticProxy(ITarget target) { super(); this.target = target; } @Override public void doA(int age) { } @Override public void doB(String name, int age) { } @Override public int getAge() { return 0; } @Override public void setAge(int age) { target.setAge(age); } }