【 DubboProtocolTest.java ====>> 客户端 ====>> DemoService.class的代理类 】
1. 构造函数:ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{ InvocationHandler.class }, new Class<?>[0], "handler=$1;");
2. 初始化:
public Object newInstance(java.lang.reflect.InvocationHandler h){
return new com.alibaba.dubbo.common.bytecode.proxy0($1);
}
3. 方法 sayHello
public void sayHello(java.lang.String arg0){
Object[] args = new Object[1];
args[0] = ($w)$1;
Object ret = handler.invoke(this, methods[12], args);
}
【 DubboProtocolTest.java ====>> 客户端 ====>> DubboInvoker.java 】
1. 字段
private final ExchangeClient[] clients;
private final Set<Invoker<?>> invokers;
private final Class<T> type;
private final URL url;
2. 方法
Class<T> getInterface();
======>>> 获取接口。
Result invoke(Invocation invocation) throws RpcException;
======>>> 调用目标方法。
【 DubboProtocolTest.java ====>> 客户端 ====>> RpcInvocation.java 】
1. 字段
private String methodName;
private Class<?>[] parameterTypes;
private Object[] arguments;
private Map<String, String> attachments;
private transient Invoker<?> invoker;
2. 方法
String getMethodName();
Class<?>[] getParameterTypes();
Object[] getArguments();
Map<String, String> getAttachments();
String getAttachment(String key);
String getAttachment(String key, String defaultValue);
Invoker<?> getInvoker();
【 DubboProtocolTest.java ====>> RPC ====>> 远程调用 】
1. 初始化 RpcInvocation
======>>> 方法名称,方法参数。
2. 初始化 Request
======>>> Request req = new Request();
======>>> req.setVersion("2.0.0");
======>>> req.setTwoWay(true);
======>>> req.setData(request);
3. NettyClient 中直接发送出去。
4. NettyServer 接收到消息,
5. 判断消息是否是Request,if (message instanceof Request){}
6. 判断是否是Event,if (request.isEvent())
7. 是否是TwoWay,if (request.isTwoWay())
8. 判断请求对象是否是坏的,if (req.isBroken())
9. 根据key来寻找目标DubboExporter,key的生成方式:key = 组名 + 服务名 + 服务版本 + 端口
public static String serviceKey(int port, String serviceName, String serviceVersion, String serviceGroup) {
StringBuilder buf = new StringBuilder();
if (serviceGroup != null && serviceGroup.length() > 0) {
buf.append(serviceGroup);
buf.append("/");
}
buf.append(serviceName);
if (serviceVersion != null && serviceVersion.length() > 0 && !"0.0.0".equals(serviceVersion)) {
buf.append(":");
buf.append(serviceVersion);
}
buf.append(":");
buf.append(port);
return buf.toString();
}
10. 调用目标方法,返回结果,invoker.invoke(inv);
11. 封装响应对象,如果调用成功,响应对象为Response res = new Response(req.getId(), req.getVersion());res.setStatus(Response.OK);res.setResult(result);
12. 返回响应对象,发送给NettyClient,channel.send(response);
13. NettyClient接收到响应消息,根绝请求ID,回去Future,DefaultFuture future = FUTURES.remove(response.getId());
14. 往future中写数据,
private void doReceived(Response res) {
lock.lock();
try {
response = res;
if (done != null) {
done.signal();
}
} finally {
lock.unlock();
}
if (callback != null) {
invokeCallback(callback);
}
}
15,主线程获取dubbo调用返回结果,
public Object get(int timeout) throws RemotingException {
if (timeout <= 0) {
timeout = Constants.DEFAULT_TIMEOUT;
}
if (! isDone()) {
long start = System.currentTimeMillis();
lock.lock();
try {
while (! isDone()) {
done.await(timeout, TimeUnit.MILLISECONDS);
if (isDone() || System.currentTimeMillis() - start > timeout) {
break;
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
if (! isDone()) {
throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
}
}
return returnFromResponse();
}
Dubbo源码阅读之 客户端远程调用
最新推荐文章于 2024-07-22 18:45:50 发布