本示例演示了采用JDK动态代理,CGLIB库的动态代理、Javassist库的动态代理及Javassist动态字节码生成代理四种动态代理的生成方法,并对这四种动态代理的对象创建及方法调用的性能进行了对比。测试结果表时:
1, JDK动态代理和CGLIB,Javassist动态字节码生成的动态代理,对方法调用的方面的性能相差不是很大。在这三者中Javassist动态字节码方式性能最好,可以达前二种方式的二倍以上。三者性能为: Javassist动态字节码>JDK动态代理>CGLIB动态代理。
2,采用Javassist工厂生成的动态代理在方法的调用上性能明显比JDK动态代理、CGLIB动态代理及Javassist动态字节码三者差,大约是后三者性能的二分之一。
3,无论何种方式实现的动态代理其性能都无法与普通代理的性能相比,并且有二个数量级的差距。
普通代理的实现:

/** * 代理类 * @author LPX * */ public class DBQueryProxy implements IDBQuery { private IDBQuery real=null; /* (non-Javadoc) * @see Pattern.DynamicProxy.IDBQuery#request() */ @Override public void request() { if(real==null){ real=new DBQuery(); } //调用被代理的对象 real.request(); } }
JDK动态代理实现:

/** * 采用JDK的动态代理处理器 * @author LPX * */ class JDKDynamicProxyHandler implements InvocationHandler{ private IDBQuery proxied=null; /** * 创建动态代理处理对象 * @param proxied */ public JDKDynamicProxyHandler(IDBQuery proxied){ this.proxied=proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用被代理的对象的方法 return method.invoke(proxied, args); } } /** * JDK动态代理 * @author LPX * */ public class JDKDynamicProxy { public static IDBQuery createDynamicProxy(){ IDBQuery proxy=(IDBQuery)Proxy.newProxyInstance(IDBQuery.class.getClassLoader(), new Class[]{IDBQuery.class}, new JDKDynamicProxyHandler(new DBQuery())); return proxy; } }
CGLIB动态代理实现:

/** * 采用CGLIB库创建的动态代理 */ package Pattern.DynamicProxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 方法执行的拦截器 * @author LPX * */ class ProxyMethodInterceptor implements MethodInterceptor{ private IDBQuery proxied=null; public ProxyMethodInterceptor(IDBQuery proxied){ this.proxied=proxied; } @Override public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { //方法拦截 return method.invoke(proxied, arg2); } } /** * CGLIB动态代理 * @author LPX * */ public class CglibDynamicProxy { public static IDBQuery createDynamicProxy(){ Enhancer enhancer=new Enhancer(); //设置方法拦截器 enhancer.setCallback(new ProxyMethodInterceptor(new DBQuery())); //设置要实现的接口列表 enhancer.setInterfaces(new Class[]{IDBQuery.class}); //产生动态代理对象 return (IDBQuery)enhancer.create(); } }
Javassist库动态代理实现:

/** * Javassist库实现的动态代理 * @return */ private static IDBQuery createJavassistProxy() { ProxyFactory factory=new ProxyFactory(); factory.setInterfaces(new Class[]{IDBQuery.class}); IDBQuery proxy=null; class ProxyMethodHandler implements MethodHandler{ private IDBQuery proxied=null; public ProxyMethodHandler(IDBQuery proxied){ this.proxied=proxied; } @Override public Object invoke(Object arg0, Method method, Method arg2, Object[] arg3) throws Throwable { //System.out.println("Javassist Method Handler invoke."); return method.invoke(proxied, arg3); } } factory.setHandler(new ProxyMethodHandler(new DBQuery())); try{ proxy=(IDBQuery)factory.create(null, null); }catch(Exception e){ e.printStackTrace(); } return proxy; }
Javassist库动态字节码代理实现:

/** * 使用Javassist动态代码实现的代理 * @return */ private static IDBQuery createJavassistBytecodeProxy() throws Throwable{ ClassPool pool=ClassPool.getDefault(); //创建一个类 CtClass ctclass=pool.makeClass(IDBQuery.class.getName()+"_javassistbytecode_proxy"); //添加要实现的接口 ctclass.addInterface(pool.get(IDBQuery.class.getName())); ctclass.addConstructor(CtNewConstructor.defaultConstructor(ctclass)); //添加域 ctclass.addField(CtField.make("public "+IDBQuery.class.getName()+" real;", ctclass)); //添加方法 ctclass.addMethod(CtNewMethod.make("public void request(){ if (real==null){ real=new " +DBQuery.class.getName()+"();} return real.request();}", ctclass)); Class pc=ctclass.toClass(); return (IDBQuery)pc.newInstance(); }
性能对比:

private static void Tuning(int type) throws Throwable{ IDBQuery proxy=null; long start=System.currentTimeMillis(); String typeName=""; switch(type){ case 1: proxy=new DBQueryProxy(); typeName="Proxy"; break; case 2: proxy=JDKDynamicProxy.createDynamicProxy(); typeName="JDKProxy"; break; case 3: proxy=CglibDynamicProxy.createDynamicProxy(); typeName="CglibProxy"; break; case 4: proxy=createJavassistProxy(); typeName="JavassistProxy"; break; case 5: proxy=createJavassistBytecodeProxy(); typeName="JavassistProxy"; break; } long end=System.currentTimeMillis(); System.out.println(typeName+" created: "+(end-start)); System.out.println(proxy.getClass().getName()); start=end; //执行3千万次,看看执行的时间是多少 for(int i=0;i<30000000;i++) proxy.request(); end=System.currentTimeMillis(); System.out.println("Call "+typeName+" request(): "+(end-start)); System.out.println(""); } /** * @param args */ public static void main(String[] args) throws Throwable { Tuning(1); Tuning(2); Tuning(3); Tuning(4); Tuning(5); }
性能输出:
Proxy created: 0
Pattern.DynamicProxy.DBQueryProxy
Call Proxy request(): 4
JDKProxy created: 4
$Proxy0
Call JDKProxy request(): 190
CglibProxy created: 50
Pattern.DynamicProxy.IDBQuery$$EnhancerByCGLIB$$b069fedf
Call CglibProxy request(): 227
JavassistProxy created: 21
Pattern.DynamicProxy.IDBQuery_$$_javassist_0
Call JavassistProxy request(): 407
JavassistProxy created: 35
Pattern.DynamicProxy.IDBQuery_javassistbytecode_proxy
Call JavassistProxy request(): 83