原处出之于阿里liangf

Interface:

package com.sunchao.jdkdyproxy;

public interface Subject {

    void request();
}

impl:

package com.sunchao.jdkdyproxy;

public class RealSubject implements Subject {
private int count;
@Override
public void request() {
count++;
//System.out.println("real subject does with the request!");
} }

jdk:

package com.sunchao.jdkdyproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class ClientProxy { public static Subject createJdkDynamicProxy(final Object delegate) {
return (Subject) Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(),
new Class<?>[] {Subject.class}, new MyInvocation(delegate));
} private static class MyInvocation implements InvocationHandler { final private Object delegate; MyInvocation(Object delegate) {
this.delegate = delegate;
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// System.out.println("aop before real request!");
return method.invoke(delegate, args);
// System.out.println("aop after real request!");
//return null;
}
} public static void main(String args[]) {
Subject delegate = new RealSubject();
Subject proxy = createJdkDynamicProxy(delegate);
proxy.request();
}
}

cglib:

package com.sunchao.cglibproxy;

import java.lang.reflect.Method;

import com.sunchao.jdkdyproxy.*;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class CglibProxy { public static Subject createCglibDynamicProxy(final Object delegate) {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(new CglibInterceptor(delegate));
enhancer.setInterfaces(new Class<?>[]{Subject.class});
Subject cglibProxy = (Subject) enhancer.create();
return cglibProxy;
} private static class CglibInterceptor implements MethodInterceptor { final private Object delegate; CglibInterceptor(Object delegate) {
this.delegate =delegate;
} @Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
//System.out.println("aop before do with the request!");
return arg1.invoke(delegate, arg2);
// System.out.println("aop before do with the request!");
//return null;
}
} public static void main(String args[]) {
Subject realSubject = new RealSubject();
Subject cglibProxy = createCglibDynamicProxy(realSubject);
cglibProxy.request(); }
}

javasist dynamic proxy:

package com.sunchao.javasistproxy;

import java.lang.reflect.Method;

import com.sunchao.jdkdyproxy.Subject;

import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject; public class ClientProxy { public static Subject createJavasistDynamicProxy(final Subject delegate)
throws Exception { ProxyFactory factory = new ProxyFactory();
factory.setInterfaces(new Class<?>[]{com.sunchao.jdkdyproxy.Subject.class});
Class<?> proxyClass = factory.createClass();
Subject javasistProxy = (Subject) proxyClass.newInstance();
((ProxyObject)javasistProxy).setHandler(new JavasistInterceptor(delegate));
return javasistProxy;
} private static class JavasistInterceptor implements MethodHandler {
final private Object delegate; JavasistInterceptor(Object delegate) {
this.delegate = delegate;
} @Override
public Object invoke(Object arg0, Method arg1, Method arg2,
Object[] arg3) throws Throwable {
//System.out.println("Aop before the real request");
return arg1.invoke(delegate, arg3);
// System.out.println("Aop after the real request");
// return null;
} }
}

javasist bytecode proxy:

package com.sunchao.javasistproxy;

import java.lang.reflect.Field;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import com.sunchao.jdkdyproxy.RealSubject;
import com.sunchao.jdkdyproxy.Subject; public class ByteCodeProxy { public static Subject createJavasistBytecodeDynamicProxy(final Subject delegate) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass proxyClass = pool.makeClass(Subject.class.getName() + "JavasistProxy");
proxyClass.addInterface(pool.get(Subject.class.getName()));
proxyClass.addConstructor(CtNewConstructor.defaultConstructor(proxyClass));
proxyClass.addField(CtField.make("private " + Subject.class.getName() + " delegate ;", proxyClass));
proxyClass.addMethod(CtNewMethod.make(
"public void request() { delegate.request();}", proxyClass));
Class<?> clazz = proxyClass.toClass();
Subject bytecodeProxy = (Subject) clazz.newInstance();
Field field = bytecodeProxy.getClass().getDeclaredField("delegate");
field.setAccessible(true);
field.set(bytecodeProxy,delegate);
return bytecodeProxy;
} public static void main(String args[]) throws Exception {
Subject delegate = new RealSubject();
Subject bytecodeProxy = createJavasistBytecodeDynamicProxy(delegate);
bytecodeProxy.request();
} }

asm:

package com.sunchao.asm;

import java.lang.reflect.Field;
import java.nio.ReadOnlyBufferException; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import com.sunchao.jdkdyproxy.RealSubject;
import com.sunchao.jdkdyproxy.Subject; public class ASMProxy { public static Subject createAsmByteCodeDynamicProxy(Subject delegate) throws Exception {
ClassWriter classWriter = new ClassWriter(true);
String className = Subject.class.getName() + "AsmProxy";
String classPath = className.replace('.', '/');
String interfacePath = Subject.class.getName().replace('.', '/'); classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, classPath, null,
"java/lang/Object", new String[] {interfacePath});
MethodVisitor initVistor = (MethodVisitor) classWriter.visitMethod(Opcodes.ACC_PUBLIC,
"<init>", "()V", null, null);
initVistor.visitCode();
initVistor.visitVarInsn(Opcodes.ALOAD, 0);
initVistor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
initVistor.visitInsn(Opcodes.RETURN);
initVistor.visitMaxs(0, 0);
initVistor.visitEnd(); FieldVisitor fieldVisitor = classWriter.visitField(Opcodes.ACC_PRIVATE, "delegate" ,
"L" + interfacePath + ";" , null, null);
fieldVisitor.visitEnd(); MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "request", "()V", null, null);
methodVisitor.visitCode();
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitFieldInsn(Opcodes.GETFIELD, classPath, "delegate", "L" + interfacePath + ";");
methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, interfacePath, "request", "()V");
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd(); classWriter.visitEnd();
byte[] code = classWriter.toByteArray();
Subject asmProxy = (Subject) new ByteArrayClassLoader().getClass(className, code).newInstance();
Field field = asmProxy.getClass().getDeclaredField("delegate");
field.setAccessible(true);
field.set(asmProxy, delegate);
return asmProxy; }
private static class ByteArrayClassLoader extends ClassLoader { ByteArrayClassLoader() {
super(ByteArrayClassLoader.getSystemClassLoader());
} public synchronized Class<?> getClass(String name, byte[] code) {
if(name == null)
throw new IllegalArgumentException("name == null");
return defineClass(name, code, 0, code.length);
}
} public static void main(String args[]) throws Exception{
Subject real = new RealSubject();
Subject asmProxy =createAsmByteCodeDynamicProxy(real);
asmProxy.request();
}
}

四种比较:

package com.sunchao.reflecttest;

import java.text.DecimalFormat;

import com.sunchao.asm.ASMProxy;
import com.sunchao.cglibproxy.CglibProxy;
import com.sunchao.javasistproxy.ByteCodeProxy;
import com.sunchao.jdkdyproxy.ClientProxy;
import com.sunchao.jdkdyproxy.RealSubject;
import com.sunchao.jdkdyproxy.Subject;
/**
*
* @author Administrator
*
*/
public class DynamicProxyTest { public static void main(String args[]) throws Exception {
Subject delegate = new RealSubject();
long time = System.currentTimeMillis();
Subject jdkProxy = ClientProxy.createJdkDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("create jdk dynamic proxy : " + time + " ms"); time = System.currentTimeMillis();
Subject cglibProxy = CglibProxy.createCglibDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("create cglib dynamic proxy : " + time + " ms"); time = System.currentTimeMillis();
Subject javasistProxy = com.sunchao.javasistproxy.ClientProxy.createJavasistDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("create javasist dynamic proxy : " + time + " ms"); time = System.currentTimeMillis();
Subject javasistbytecodeProxy = ByteCodeProxy.createJavasistBytecodeDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("create javasist bytecode proxy : " + time + " ms" ); time = System.currentTimeMillis();
Subject asmProxy = ASMProxy.createAsmByteCodeDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("create asm bytecode proxy : " + time + " ms");
System.out.println("<============================================>");
for(int i = 0; i < 3; i++){
test(jdkProxy, "run the jdkDynamicProxy : ");
test(cglibProxy, "run the cglibDynamicProxy : ");
test(javasistProxy, "run the javasistProxy : ");
test(javasistbytecodeProxy, "run the javasist byte code proxy : ");
test(asmProxy, "run the asm byte code proxy : ");
System.out.println("<-------------------------------------->");
} } public static void test(Subject delegate, String label) {
delegate.request();//warm up
int count = 10000000;
long time = System.currentTimeMillis();
for(int i = 0; i < count; i++){
delegate.request();
}
time = System.currentTimeMillis() - time;
System.out.println(label + time + " ms, " + new DecimalFormat().format(count * 1000 / time) + " t/s");
} } 四种比较结果:

create jdk dynamic proxy : 9 ms
create cglib dynamic proxy : 169 ms
create javasist dynamic proxy : 109 ms
create javasist bytecode proxy : 375 ms
create asm bytecode proxy : 9 ms
<============================================>
run the jdkDynamicProxy : 864 ms, 1,632,020 t/s
run the cglibDynamicProxy : 794 ms, 1,775,901 t/s
run the javasistProxy : 816 ms, 1,728,021 t/s
run the javasist byte code proxy : 80 ms, 17,625,817 t/s
run the asm byte code proxy : 76 ms, 18,553,492 t/s
<-------------------------------------->
run the jdkDynamicProxy : 707 ms, 1,994,434 t/s
run the cglibDynamicProxy : 713 ms, 1,977,651 t/s
run the javasistProxy : 862 ms, 1,635,806 t/s
run the javasist byte code proxy : 66 ms, 21,364,627 t/s
run the asm byte code proxy : 73 ms, 19,315,964 t/s
<-------------------------------------->
run the jdkDynamicProxy : 740 ms, 1,905,493 t/s
run the cglibDynamicProxy : 693 ms, 2,034,726 t/s
run the javasistProxy : 844 ms, 1,670,693 t/s
run the javasist byte code proxy : 74 ms, 19,054,937 t/s
run the asm byte code proxy : 83 ms, 16,988,739 t/s
<-------------------------------------->

四种各种调用10000000次:

从创建动态代理类的时间可以看出:jdk和asm效果最优,javasist bytecode次之,在其次cglib,最差的是javasist dynamic proxy
从代理调用的时间可以看出:asm和javasist差不多最好,其他三个差不多,差距较大;
asm比较底层,对虚拟机指令要求高,综合javasist bytecode性能综合比较好,

Java 几种动态代理实现及其性能比较的更多相关文章

  1. java两种动态代理方式的理解

    要理解动态代理,不妨先来看看一个静态代理的例子. 一.静态代理 以一个电商项目的例子来说明问题,比如我定义了一个订单的接口IOrder,其中有一个方法时delivery,代码如下. package c ...

  2. 使用Java中的动态代理实现数据库连接池

    2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...

  3. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

  4. 杨晓峰-Java核心技术-6 动态代理 反射 MD

    目录 第6讲 | 动态代理是基于什么原理? 典型回答 考点分析 知识扩展 反射机制及其演进 动态代理 精选留言 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAnd ...

  5. Jmh测试JDK,CGLIB,JAVASSIST动态代理方式的性能

    前言 JDK,CGLIB,JAVASSIST是常用的动态代理方式. JDK动态代理仅能对具有接口的类进行代理. CGLIB动态代理方式的目标类可以没有接口. Javassist是一个开源的分析.编辑和 ...

  6. 一文读懂Java中的动态代理

    从代理模式说起 回顾前文: 设计模式系列之代理模式(Proxy Pattern) 要读懂动态代理,应从代理模式说起.而实现代理模式,常见有下面两种实现: (1) 代理类关联目标对象,实现目标对象实现的 ...

  7. Java基础-CGLIB动态代理

    JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继 ...

  8. java 笔记(3) —— 动态代理,静态代理,cglib代理

    0.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口. 代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存 ...

  9. Java反射和动态代理

    Java反射 反射机制 RTTI 编译器在编译时打开和检查*.class文件 反射机制 运行时打开和检查*.class文件 Java反射常见的方法 java反射的应用 setAccessible(bo ...

随机推荐

  1. tophat安装

    1     依赖软件:bowtie,bowtie2,samtools,boost c++ library 2     建立索引文件:      bowtie包括bowtie,bowtie-build, ...

  2. Ajax同源和跨域

    ajax跨域访问 客户端页面 var url = "http://172.16.91.121:81/FellIn/FellIn.aspx?Action=WXSave&WX_Store ...

  3. Node.js 蚕食计划(三)—— Express 启航

    如果看过上一篇<Node.js 蚕食计划>,就会发现手动搭建一个 web 服务器还是比较繁琐 而 express 就是一个可以极大地提高开发效率的 web 开发框架 一.创建项目 在 ex ...

  4. PHP 微信分享页面(图文)

    首先确保你的公众号配置没有问题,详细请看: PHP 微信公众号-创建菜单-配置 1.获取签名包 这里需要你的appid 和 开发者密码 //获取签名包 public function getSignP ...

  5. 用Python让单片机“行动”起来——MicroPython实战入门篇

    MicroPython以微控制器作为目标,从而使得Python可以用来控制硬件.说到MicroPython,也许有人会感到陌生.而说到和它密切相关的Python,是否会恍然大悟呢?Python属于解释 ...

  6. GBK,UNICODE,GB2312,UTF-8学习总结

    转自http://www.cnblogs.com/pannengzhi/p/5678495.html UNICODE,GBK,UTF-8区别 前言 其实这是个老生常谈的问题了,相信大家在第一次遇到Un ...

  7. 常见的DBCP连接池配置

    项目中使用mybatis出现一个问题,项目刚启动时,查询项目列表是ok的,过上一段时间之后,再次查询项目列表,查询失败,初步判断是因为mysql的连接问题,最后查阅资料,发现是连接池中的连接失效,导致 ...

  8. UWP 手绘视频创作工具技术分享系列 - 全新的 UWP 来画视频

    从2017年11月开始,我们开始规划和开发全新的来画Pro,在12月23日的短视频峰会上推出了预览版供参会者体验,得到了很高的评价和关注度.吸取反馈建议后,终于在2018年1月11日正式推出了全新版本 ...

  9. 一个InnoDB性能超过Oracle的调优Case

    年前抽空到兄弟公司支援了一下Oracle迁移MySQL的测试,本想把MySQL调优到接近Oracle的性能即可,但经过 @何_登成 @淘宝丁奇 @淘宝褚霸 @淘伯松 诸位大牛的指导和帮助(排名不分先后 ...

  10. 二叉树——遍历篇(递归/非递归,C++)

    二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...