前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dubbo源码学习笔记----RPC

dubbo源码学习笔记----RPC

作者头像
春哥大魔王
发布2018-04-17 17:49:33
6370
发布2018-04-17 17:49:33
举报
文章被收录于专栏:服务端技术杂谈

RpcContext

整个RpcContext通过ThreadLocal维持。

代码语言:javascript
复制
public class RpcContext {    private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() {
        @Override        protected RpcContext initialValue() {            return new RpcContext();
        }
    };    private final Map<String, String> attachments = new HashMap<String, String>();    private final Map<String, Object> values = new HashMap<String, Object>();    private Future<?> future;    private List<URL> urls;    private URL url;    private String methodName;    private Class<?>[] parameterTypes;    private Object[] arguments;    private InetSocketAddress localAddress;    private InetSocketAddress remoteAddress;
    @Deprecated    private List<Invoker<?>> invokers;
    @Deprecated    private Invoker<?> invoker;
    @Deprecated    private Invocation invocation;

通过isProviderSide,isConsumerSide标记Context属于服务提供方还是服务使用方。

通过Future从Context中获取异步调用结果:

代码语言:javascript
复制
    public <T> Future<T> asyncCall(Callable<T> callable) {        try {            try {
                setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());                final T o = callable.call();                //local invoke will return directly
                if (o != null) {
                    FutureTask<T> f = new FutureTask<T>(new Callable<T>() {                        public T call() throws Exception {                            return o;
                        }
                    });
                    f.run();                    return f;
                } else {

                }
            } catch (Exception e) {                throw new RpcException(e);
            } finally {
                removeAttachment(Constants.ASYNC_KEY);
            }
        } catch (final RpcException e) {            return new Future<T>() {                public boolean cancel(boolean mayInterruptIfRunning) {                    return false;
                }                public boolean isCancelled() {                    return false;
                }                public boolean isDone() {                    return true;
                }                public T get() throws InterruptedException, ExecutionException {                    throw new ExecutionException(e.getCause());
                }                public T get(long timeout, TimeUnit unit)
                        throws InterruptedException, ExecutionException,
                        TimeoutException {                    return get();
                }
            };
        }        return ((Future<T>) getContext().getFuture());
    }

服务调用

代码语言:javascript
复制
public class RpcInvocation implements Invocation, Serializable {    private static final long serialVersionUID = -4355285085441097045L;    private String methodName;    private Class<?>[] parameterTypes;    private Object[] arguments;    private Map<String, String> attachments;    private transient Invoker<?> invoker;

代理调用

代码语言:javascript
复制
public class JavassistProxyFactory extends AbstractProxyFactory {    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {        return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
    }

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {        // TODO Wrapper cannot handle this scenario correctly: the classname contains '$'
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? 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);
            }
        };
    }

}


public class JdkProxyFactory extends AbstractProxyFactory {    @SuppressWarnings("unchecked")
    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {        return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(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);
            }
        };
    }

}

RedisProtocol

比较有意思,是通过对invocation.Arguments作为key放到redis中取值,将值反序列化出来作为执行结果。

代码语言:javascript
复制
          resource = jedisPool.getResource();                        if (get.equals(invocation.getMethodName())) {                            if (invocation.getArguments().length != 1) {                                throw new IllegalArgumentException("The redis get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                            }                            byte[] value = resource.get(String.valueOf(invocation.getArguments()[0]).getBytes());                            if (value == null) {                                return new RpcResult();
                            }
                            ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));                            return new RpcResult(oin.readObject());
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 春哥talk 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RpcContext
  • 服务调用
  • 代理调用
  • RedisProtocol
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档