zoukankan      html  css  js  c++  java
  • 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生成字节码并实例化对象返回

  • 相关阅读:
    linux下安装jdk1.8
    在eclipse里面启动tomcat服务器时报错Server Tomcat v7.0 Server at localhost failed to start.
    frame使关闭口生效
    web.xml配置错误处理节点
    mac下修改mysql默认字符集为utf8
    Centos6.5关闭防火墙命令
    mysql修改
    java错误:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build
    完美解决Linux服务器tomcat开机自启动问题
    MAC 查看java home目录
  • 原文地址:https://www.cnblogs.com/heart-king/p/5642866.html
Copyright © 2011-2022 走看看