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

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



JavassistProxyFactory:利用字节码技术来创建对象

public <T> T getProxy(Invoker<T> invoker,Class<?>[] interfaces) {

       return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));

}

看似跟jdk生成代理一样, 其实这里的Proxy类不是jdk中自带那个生成代理对象的类是:

  com.alibaba.dubbo.common.bytecode.Proxy

这个dubbo自己写的Proxy类,利用要代理的接口利用javassist工具生成代理代码。

获取Invoker 对象

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {

        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf(‘$‘) < 0 ? proxy.getClass() : type);

        return new AbstractProxyInvoker<T>(proxy, type, url) {

            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以map为缓存查找如果有,说明代理对象已创建返回

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生成字节码并实例化对象返回

时间: 2025-01-14 23:48:05

5.Dubbo原理解析-代理之Javassist字节码技术生成代理 (转)的相关文章

Dubbo源码分析(八):Javassist字节码技术生成代理

Java动态编程的作用:      通过配置生成代码,减少重复编码和维护成本 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不会频繁使用反射,因为反射的性能开销较大.其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassit. Javassit其实就是一个二方包,提供了运行时操作Java字节码的方法.大家都知道,Java代码编译完会生成.class文件,就是一堆字节码.JVM(准确说是JIT)会解释执行这些字节码(转换为机

4. Dubbo原理解析-代理之接口定义 (转)

转载自  斩秋的专栏  http://blog.csdn.net/quhongwei_zhanqiu/article/details/41577159 一:ProxyFactory的接口定义 import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.common.extension.Adaptive; import com.alibaba.dub

字节码技术及动态代理

.output_wrapper pre code { font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; overflow: auto !important } .task-list-list { list-style-type: none } .task-list-list.checked { color: rgb(62,

动态字节码技术 javassist 初探

字节码应用场景AOP 技术.Lombok 去除重复代码插件.动态修改 class 文件等字节码技术优势Java 字节码增强指的是在 Java 字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修改,Java 字节码增强主要是为了减少冗余代码,提高性能等 实现字节码增强的主要步骤为:修改字节码,在内存中获取到原来的字节码,然后通过一些工具(如 ASM,Javaasist)来修改它的byte[]数组,得到一个新的byte数组使修改后的字节码生效 自定义 ClassLo

2. Dubbo原理解析-Dubbo内核实现之基于SPI思想Dubbo内核实现(转)

转载自  斩秋的专栏  http://blog.csdn.net/quhongwei_zhanqiu/article/details/41577159 SPI接口定义 定义了@SPI注解 public @interface SPI { String value() default ""; //指定默认的扩展点 } 只有在接口打了@SPI注解的接口类才会去查找扩展点实现 会依次从这几个文件中读取扩展点 META-INF/dubbo/internal/   //dubbo内部实现的各种扩展

12. Dubbo原理解析-注册中心之基于dubbo协议的简单注册中心实现

基于dubbo协议开源只是给出了默认一个注册中心实现SimpleRegistryService, 它只是一个简单实现,不支持集群,就是利用Map<String/*ip:port*/, Map<String/*service*/, URL>来存储服务地址, 具体不在啰嗦了,请读者翻看源代码,可作为自定义注册中的参考. 注册中心启动 SimpleRegistryService本身也是作为一个dubbo服务暴露. <dubbo:protocolport="9090"

Javassist字节码增强示例

概述 Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果.熟练使用这套工具,可以让Java编程更接近与动态语言编程. 下面一个方法的目的是获取一个类加载器(ClassLoader),以加载指定的.jar或.class文件,在之后的代码中会使用到. [java] view plaincopy private static ClassLoader getLocaleClassLoader() throws Exception {

搭建agent服务+javassist字节码操作

简介 对于agent,是在vm启动,执行方法前,将字节码修改的服务代理. 对于javassist,是修改字节码具体实现. 这两个结合有什么用啊?写测试框架,不仅局限于此. 对于字节码: 字节码处理工具,bcel,asm与虚拟机指令打交道.Javassist采用java编码的方法处理字节码,性能相对较低,但方便. 官方:http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/ 例子: 创建class http://blog.csdn.net/sadfi

JAVAssist字节码操作

Java动态性的两种常见实现方式 字节码操作 反射 运行时操作字节码可以让我们实现如下功能: 动态生成新的类 动态改变某个类的结构(添加/删除/修改  新的属性/方法) 优势: 比反射开销小,性能高 JAVAasist性能高于反射,低于ASM 常见的字节码操作类库 BCEL 这是Apache Software Fundation的jakarta项目的一部分.BCEL是javaclassworking广泛使用的一种跨级啊,它可以让你深入JVM汇编语言进行类的操作的细节.BCEL与javassist