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

  • 相关阅读:
    取得GridPanel选定行所有字段值
    从少林寺的核心竞争力看软件作坊和正规军的差异
    估算软件项目成本
    Delphi FastReport报表常用方法
    少林寺的组织结构分析
    embed标签使用
    C# 多种方式播放Wav声音
    js 关闭浏览器
    ExtJS GridPanel根据条件改变字体颜色
    [Jsp] 如何在JSP页面快速输出从Servlet接收的数据_看JSTL常用C标签的威力
  • 原文地址:https://www.cnblogs.com/heart-king/p/5642866.html
Copyright © 2020-2023  润新知