美文网首页
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