美文网首页
hsf笔记-Consumer调用基本流程

hsf笔记-Consumer调用基本流程

作者: 兴浩 | 来源:发表于2018-08-14 11:21 被阅读47次

1.ConsumerServiceModel

先参考此篇:https://www.jianshu.com/p/f67757927f0e

    private Object consume(ServiceMetadata metadata) {
        if (this.applicationModel.getConsumedServiceModel(metadata.getUniqueName()) != null) {
            return this.applicationModel.getConsumedServiceModel(metadata.getUniqueName()).getProxyObject();
        } else {
            ProxyDecoratorGenerator proxyDecoratorGenerator = (ProxyDecoratorGenerator)HSFServiceContainer.getInstance(ProxyDecoratorGenerator.class);
            Class<?>[] decorateInterfaces = proxyDecoratorGenerator.getDecorateInterfaces(metadata);
            ProxyFactory proxyFactory = (ProxyFactory)HSFServiceContainer.getInstance(ProxyFactory.class, metadata.getProxyStyle());
            Object proxy = proxyFactory.getProxy(metadata, decorateInterfaces);
            Method[] methods = proxyFactory.getMethods(proxy);
            ConsumerServiceModel consumerServiceModel = new ConsumerServiceModel(metadata, proxy, methods);
            metadata.setConsumerServiceModel(consumerServiceModel);
            this.applicationModel.initConsumerService(metadata.getUniqueName(), consumerServiceModel);
            metadata.referSync();
            return proxy;
        }
    }

1.1 ConsumerServiceModel

在生成代理对象的同时,会将相关对象属性存储起来,如下图


此时ServiceMetadata拥有一个ConsumerServiceModel

public class ConsumerServiceModel {
    private final ServiceMetadata metadata;
    private final Object proxyObject;
    private final Map<Method, ConsumerMethodModel> methodModels = new IdentityHashMap();

    public ConsumerServiceModel(ServiceMetadata metadata, Object proxyObject, Method[] methods) {
        this.metadata = metadata;
        this.proxyObject = proxyObject;
        if (proxyObject != null) {
            Method[] arr$ = methods;
            int len$ = methods.length;

            for(int i$ = 0; i$ < len$; ++i$) {
                Method method = arr$[i$];
                this.methodModels.put(method, new ConsumerMethodModel(method, metadata));
            }
        }

    }

    public ServiceMetadata getMetadata() {
        return this.metadata;
    }

    public Object getProxyObject() {
        return this.proxyObject;
    }

    public ConsumerMethodModel getMethodModel(Method method) {
        return (ConsumerMethodModel)this.methodModels.get(method);
    }

    public List<ConsumerMethodModel> getAllMethods() {
        return new ArrayList(this.methodModels.values());
    }

    public String getServiceName() {
        return this.metadata.getUniqueName();
    }
}

1.2 ConsumerMethodModel

ConsumerMethodModel对Method对象进行了包装抽象

public class ConsumerMethodModel {
    private static final String TIMEOUT_TYPE_KEY = "_TIMEOUT";
    private static final String ALL_METHODS = "*";
    private final Method method;
    private final ServiceMetadata metadata;
    private final boolean isCallBack;
    private final boolean isFuture;
    private final String[] parameterTypes;
    private final Class<?>[] parameterClasses;
    private final Class<?> returnClass;
    private final String methodName;
    private final int executeTimes;
    private final boolean generic;
    private final String invokeType;
    private final boolean isReliable;
    private final int timeout;
    public static final AttributeNamespace ATTRIBUTE_NAMESPACE = AttributeNamespace.createNamespace("consumer_method_attribute");
    private ConcurrentAttributeMap attributeMap;

    public ConsumerMethodModel(Method method, ServiceMetadata metadata) {
        this.attributeMap = new ConcurrentAttributeMap(ATTRIBUTE_NAMESPACE, 4);
        this.method = method;
        this.parameterClasses = method.getParameterTypes();
        this.returnClass = method.getReturnType();
        this.parameterTypes = this.createParamSignature(this.parameterClasses);
        this.methodName = method.getName();
        this.metadata = metadata;
        this.generic = this.methodName.equals("$invoke") && this.parameterTypes != null && this.parameterTypes.length == 3;
        this.isCallBack = metadata.isCallBackMethod(this.methodName);
        this.isFuture = metadata.isFutureMethod(this.methodName);
        this.executeTimes = metadata.getRetries(this.methodName) + 1;
        this.isReliable = metadata.isReliableMethod(this.methodName);
        this.timeout = this.createTimeout();
        this.invokeType = this.judgeInvokeType(metadata);
    }
}

2.Consumer调用流程

image.png

当Consumer调用一个方法时,上图的入口点由ProxyInvocationHandler的invoke方法发起

  1. 首先要获取到已经准备好的MethodModel
  2. 调用InvocationUtil.invoke静态方法
  3. 在远程调用时,会将参数转换成为一个Invocation
  4. 调用的对方为SyncInvocationHandler,表示同步调用的接口
  5. 远程调用结果为RPCResult
public interface SyncInvocationHandler {
    RPCResult invoke(Invocation invocation) throws Throwable;
}

关于Invocation和SyncInvocationHandler的构建,后面再分析

相关文章

网友评论

      本文标题:hsf笔记-Consumer调用基本流程

      本文链接:https://www.haomeiwen.com/subject/qesmbftx.html