zoukankan      html  css  js  c++  java
  • dubbo源码阅读-ProxyFactory(十一)之StubProxyFactoryWrapper本地存根

    说明

    Wrapper调用时机可以看:https://www.cnblogs.com/LQBlog/p/12470179.html#autoid-2-0-0

    /**
     * StubProxyFactoryWrapper
     */
    public class StubProxyFactoryWrapper implements ProxyFactory {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(StubProxyFactoryWrapper.class);
    
        private final ProxyFactory proxyFactory;
    
        private Protocol protocol;
    
        //注意构造函数
        public StubProxyFactoryWrapper(ProxyFactory proxyFactory) {
            this.proxyFactory = proxyFactory;
        }
    
        public void setProtocol(Protocol protocol) {
            this.protocol = protocol;
        }
    
        @Override
        public <T> T getProxy(Invoker<T> invoker, boolean generic) throws RpcException {
            return proxyFactory.getProxy(invoker, generic);
        }
    
        @Override
        @SuppressWarnings({"unchecked", "rawtypes"})
        public <T> T getProxy(Invoker<T> invoker) throws RpcException {
            //获得代理对象
            T proxy = proxyFactory.getProxy(invoker);
            //如果不是泛型化
            if (GenericService.class != invoker.getInterface()) {
                //获取stub配置如果未配置获取local(兼容老配置)
                String stub = invoker.getUrl().getParameter(Constants.STUB_KEY, invoker.getUrl().getParameter(Constants.LOCAL_KEY));
                //是否有配置
                if (ConfigUtils.isNotEmpty(stub)) {
                    //获取接口
                    Class<?> serviceType = invoker.getInterface();
                    //是否是配置的 true或者default
                    if (ConfigUtils.isDefault(stub)) {
                        if (invoker.getUrl().hasParameter(Constants.STUB_KEY)) {
                            //获取接口名字+Stub
                            stub = serviceType.getName() + "Stub";
                        } else {
                            //获取接口名字+Local
                            stub = serviceType.getName() + "Local";
                        }
                    }
                    try {
                        //反射获取class
                        Class<?> stubClass = ReflectUtils.forName(stub);
                        if (!serviceType.isAssignableFrom(stubClass)) {
                            throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + serviceType.getName());
                        }
                        try {
                            //stub类必须含有当前代理接口类型的构造函数
                            Constructor<?> constructor = ReflectUtils.findConstructor(stubClass, serviceType);
                            //创建实例并传入代理类
                            proxy = (T) constructor.newInstance(new Object[]{proxy});
                            //export stub service
                            URL url = invoker.getUrl();
                            //是否有配置 dubbo.stub.event 事件监听器
                            if (url.getParameter(Constants.STUB_EVENT_KEY, Constants.DEFAULT_STUB_EVENT)) {
                                url = url.addParameter(Constants.STUB_EVENT_METHODS_KEY, StringUtils.join(Wrapper.getWrapper(proxy.getClass()).getDeclaredMethodNames(), ","));
                                url = url.addParameter(Constants.IS_SERVER_KEY, Boolean.FALSE.toString());
                                try {
                                    export(proxy, (Class) invoker.getInterface(), url);
                                } catch (Exception e) {
                                    LOGGER.error("export a stub service error.", e);
                                }
                            }
                        } catch (NoSuchMethodException e) {
                            throw new IllegalStateException("No such constructor "public " + stubClass.getSimpleName() + "(" + serviceType.getName() + ")" in stub implementation class " + stubClass.getName(), e);
                        }
                    } catch (Throwable t) {
                        LOGGER.error("Failed to create stub implementation class " + stub + " in consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", cause: " + t.getMessage(), t);
                        // ignore
                    }
                }
            }
            //最终返回的是Stub代理类
            return proxy;
        }
    
        @Override
        public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException {
            return proxyFactory.getInvoker(proxy, type, url);
        }
    
        private <T> Exporter<T> export(T instance, Class<T> type, URL url) {
            return protocol.export(proxyFactory.getInvoker(instance, type, url));
        }
    
    }
  • 相关阅读:
    PHP入门(二)
    PHP入门(一)
    TypeScript作为前端开发你必须学习的技能(三)
    东北师范大学-构建之法-20201022作业成绩
    20201108-东北师范大学-助教-周总结-第8次
    20201103-东北师范大学-助教-周总结-第7次
    东北师范大学-构建之法-20201015作业成绩
    20201026-东北师范大学-助教-周总结-第6次
    东北师范大学-构建之法-20201008作业成绩
    20201019-东北师范大学-助教-周总结-第5次
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12510187.html
Copyright © 2011-2022 走看看