JavassistProxyFactory利用自己吗技术构建代理对象的实现如下:

public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}

  看似和使用jdk技术生成代理对象一样,实际上这里的Proxy类不是jdk自带的,而是dubbo自己实现的com.alibaba.dubbo.common.bytecode.Proxy,利用javassist工具生成代理代码。

  JavassistProxyFactory中获取Invoker 对象对象的实现如下:

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// TODO Wrapper类不能正确处理带$的类名
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < ? proxy.getClass() : type);
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}

  根据传入的 proxy对象的类信息创建它的包装对象Wrapper,返回Invoker对象实例, 这个invoker对象invoke方法可以根据传入的invocation对象中包含的方法名,方法参数来调用proxy对象返回调用结果。

  com.alibaba.dubbo.common.bytecode.Proxy 生成代理对象的工具类,实现逻辑如下:
  1.遍历所有入参接口,以;分割连接起来, 以它为key从cache中查找如果有,说明代理对象已创建返回

  2.利用AtomicLong对象自增获取一个long数组来作为生产类的后缀,防止冲突

  3.遍历接口获取所有定义的方法,加入到一个集合Set<String> worked中 ,用来判重,获取方法y应该在methods数组中的索引下标ix,获取方法的参数类型以及返回类型,构建方法体return  ret= handler.invoke(this, methods[ix], args);这里的方法调用其实是委托给InvokerInvocationHandler实例对象的,去调用真正的实例,方法加入到methods数组中。

  4.创建代理实例对象ProxyInstance。类名为  pkg + “.poxy”+id = 包名 + “.poxy” +自增数值,添加静态字段Method[] methods,添加实例对象InvokerInvocationHandler hanler,添加构造器参数是InvokerInvocationHandler,添加无参构造器,利用工具类ClassGenerator生成对应的字节码。

  5.创建代理对象,它的newInstance(handler)方法用来创建基于我们接口的代理,代理对象名Proxy + id,

继承于Proxy, 所以要实现newInstance方法。添加默认构造器。实现方法newInstance代码, new pcn(hadler) 这里pcn就是前面生成的代理对象类名。利用工具类ClassGenerator生成字节码并实例化对象返回。

// create Proxy class.
String fcn = Proxy.class.getName() + id;
ccm = ClassGenerator.newInstance(cl);
ccm.setClassName(fcn);
ccm.addDefaultConstructor();
ccm.setSuperClass(Proxy.class);
ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
Class<?> pc = ccm.toClass();
proxy = (Proxy) pc.newInstance();

Dubbo原理实现之使用Javassist字节码结束构建代理对象的更多相关文章

  1. 5.Dubbo原理解析-代理之Javassist字节码技术生成代理 (转)

    转载自  斩秋的专栏  http://blog.csdn.net/quhongwei_zhanqiu/article/details/41597219 JavassistProxyFactory:利用 ...

  2. JVM 内部原理(七)— Java 字节码基础之二

    JVM 内部原理(七)- Java 字节码基础之二 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...

  3. JVM 内部原理(六)— Java 字节码基础之一

    JVM 内部原理(六)- Java 字节码基础之一 介绍 版本:Java SE 7 为什么需要了解 Java 字节码? 无论你是一名 Java 开发者.架构师.CxO 还是智能手机的普通用户,Java ...

  4. Javassist 字节码 语法 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  6. 字节码技术---------动态代理,lombok插件底层原理。类加载器

    字节码技术应用场景 AOP技术.Lombok去除重复代码插件.动态修改class文件等 字节技术优势  Java字节码增强指的是在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用 ...

  7. Javassist 字节码操作

    1.读写字节码 Javassist是用来处理java字节码的类库.字节码保存在二进制文件中称为类文件.每个类文件夹包括一个java类或接口. Javasssist.CtClass这个类是一个类文件的抽 ...

  8. Javassist字节码增强示例

    概述 Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果.熟练使用这套工具,可以让Java编程更接近与动态语言编程. 下面一个方 ...

  9. JAVAssist字节码操作

    Java动态性的两种常见实现方式 字节码操作 反射 运行时操作字节码可以让我们实现如下功能: 动态生成新的类 动态改变某个类的结构(添加/删除/修改  新的属性/方法) 优势: 比反射开销小,性能高 ...

随机推荐

  1. 使用xtrabackup备份innodb引擎的数据库

    innodb引擎的数据库可以使用mysqldump备份,如果表很大几十个G甚至上百G,显示用mysqldump备份会非常慢.然后使用xtrabackup 可以很快的在线备份innodb数据库.Inno ...

  2. OpenCV-图像通道转换问题

    OpenCV-MAT对象中使用plt.imshow(img[:,:,::-1])如何实现将第二轴反向? 系统平台:win10 x64 一.明确几个概念: 1.OpenCV内部每个通道并没有固定对应某种 ...

  3. centos7 虚拟机安装docker-ce-17.09

    1.创建虚拟机使用iso镜像centos-x86_64-7.3.1611 2.安装centos选择桌面版 3.配置命令行环境,网卡(见博客另一篇文章) 4.安装container-selinux-2. ...

  4. Explain结果解读与实践

    MySQL的EXPLAIN命令用于SQL语句的查询执行计划(QEP).这条命令的输出结果能够让我们了解MySQL 优化器是如何执行SQL 语句的.这条命令并没有提供任何调整建议,但它能够提供重要的信息 ...

  5. linux vi操作

    1.“i”键,进入编辑状态.可以看到命令的下方出现了“--INSERT--”字样,表示成功进入了编辑模式; 2.“Esc”键,退出编辑模式.并在此时输入“:wq”以退出并保存

  6. 关于redis,学会这9点就够了

    一.redis是什么 redis是一种支持Key-Value等多种数据结构的存储系统.可用于缓存.事件发布或订阅.高速队列等场景.该数据库使用ANSI C语言编写,支持网络,提供字符串.哈希.列表.队 ...

  7. springboot 碰到的问题

    1.在springboot 启动报错 ** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentS ...

  8. GDI基础(1):绘制线条和图形

    1. 绘制一个像素点:SetPixel(). 绘制直线:MoveTo(),LineTo(). 绘制多个首尾相连的线:Polyline(). 绘制矩形:FrameRect(),Rectangle(),F ...

  9. JAVA经典算法40+

    现在是3月份,也是每年开年企业公司招聘的高峰期,同时有许多的朋友也出来找工作.现在的招聘他们有时会给你出一套面试题或者智力测试题,也有的直接让你上机操作,写一段程序.算法的计算不乏出现,基于这个原因我 ...

  10. verilog中的多维数组

    reg  arrayb [7:0] [0:255] ;//二维数组.