zoukankan      html  css  js  c++  java
  • Dubbo原理实现之代理接口的定义

      Dubbo有很多的实现采用了代码模式,Dubbo由代理工厂ProxyFactory对象创建代理对象。

      ProxyFactory接口的定义如下:

    @SPI("javassist")
    public interface ProxyFactory {
    
        /**
         * create proxy.
         *
         * @param invoker
         * @return proxy
         */
        @Adaptive({Constants.PROXY_KEY})
        <T> T getProxy(Invoker<T> invoker) throws RpcException;
    
        /**
         * create invoker.
         *
         * @param <T>
         * @param proxy
         * @param type
         * @param url
         * @return invoker
         */
        @Adaptive({Constants.PROXY_KEY})
        <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
    
    }

      @SPI指定默认使用javassist字节码技术来生成代理对象,接口定义了生成代理对象的方法getProxy, 入参是invoker对象,接口定义了获取invoker对象, invoker对象是个可执行对象,这里inovker对象的invoke方法其实执行的是根据url获取的方法对第一个入参的实体对象的调用,即:如果url的得知调用方法sayHello,  入参proxy为空Test对象实现test,那invoker.invoke()就是test.sayHello()。

      代理工厂的实现类图如下:

      

      AbstractProxyFactory: 代理工厂的公共抽象, 这里抽象实现主要是获取需要代理的接口,代理接口可以在设置在url中,key为interfaces, 如果是多个接口用逗号分隔, 如果没有在url中指定,获取invoke接口和EchoService接口

    public <T> T getProxy(Invoker<T> invoker) throws RpcException {
            Class<?>[] interfaces = null;
            String config = invoker.getUrl().getParameter("interfaces");
            if (config != null && config.length() > 0) {
                String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
                if (types != null && types.length > 0) {
                    interfaces = new Class<?>[types.length + 2];
                    interfaces[0] = invoker.getInterface();
                    interfaces[1] = EchoService.class;
                    for (int i = 0; i < types.length; i++) {
                        interfaces[i + 1] = ReflectUtils.forName(types[i]);
                    }
                }
            }
            if (interfaces == null) {
                interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class};
            }
            return getProxy(invoker, interfaces);
        }

      JdkProxyFactory: 利用jdk动态代理来创建代理,实现比较简单

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

      InvokerInvocationHandler是jdk动态代理创建一定要构建的参数,这里它的invoke方法只是简单的调用了invoker.invoke方法,  Invoker在dubbo中代表一个可执行体,一切都向它靠拢。

      获取invoker对象

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
            return new AbstractProxyInvoker<T>(proxy, type, url) {
                @Override
                protected Object doInvoke(T proxy, String methodName,
                                          Class<?>[] parameterTypes,
                                          Object[] arguments) throws Throwable {
                    Method method = proxy.getClass().getMethod(methodName, parameterTypes);
                    return method.invoke(proxy, arguments);
                }
            };
        }

      这里创建的 Invoker对象,执行invoke方法,其实就是利用反射技术结合入参执行对应对象的对应方法。

  • 相关阅读:
    Python——项目-小游戏_正式的进入开发阶段_1阶段 主程序&背景移动
    Ajax-使用教程
    JavaScript——类还有对象
    Python——项目-小游戏3-精灵?蓝精灵?
    Python——项目-小游戏2-动画绘制
    jQuery——有关于jQuery操作 属性,元素,还有尺寸位置等
    Python——项目-小游戏
    jQuery入门
    JavaScript——WEBAPIS_有关于移动端特效,还有本地存储
    性能优化之Angular前端优化总结
  • 原文地址:https://www.cnblogs.com/senlinyang/p/8626720.html
Copyright © 2011-2022 走看看