dubbo-源码阅读之服务发布

原理

dubbo根据spring 2.0的schma实现 解析xml并初始化相关bean 初始化dubbo:service为ServiceBean实例  通过spring的生命周期相应回调实现服务发布

ServiceBean源码

import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * InitializingBean
 *  1.初始化的时候会调用afterPropertiesSet方法
 *  2.优先级高于init-method
 *  3.如果afterPropertiesSet出现异常 则不调用init-method
 * DisposableBean
 *  1.当调用context.close的时候会执行destroy
 * ApplicationContextAware
 *  1.初始化对象会传入spring上下文容器
 * ApplicationListener事件
 *  1.ContextRefreshedEvent
 *     ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。
 *     此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用
 *  2.ContextStartedEvent
 *    当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。
 *    你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序
 *  3.ContextStoppedEvent
 *    当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作
 *  4.ContextClosedEvent
 *    当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启
 *  5.RequestHandledEvent
 *    这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。
 *    在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件
 * @param <T>
 */
  class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware {

    /**
     * ApplicationContextAware接口实现方法
     * @param applicationContext
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        SpringExtensionFactory.addApplicationContext(applicationContext);
        if (applicationContext != null) {
            SPRING_CONTEXT = applicationContext;

            try {
                Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class);
                method.invoke(applicationContext, this);
                this.supportedApplicationListener = true;
            } catch (Throwable var5) {
                if (applicationContext instanceof AbstractApplicationContext) {
                    try {
                        Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class);
                        if (!method.isAccessible()) {
                            method.setAccessible(true);
                        }

                        method.invoke(applicationContext, this);
                        this.supportedApplicationListener = true;
                    } catch (Throwable var4) {
                        ;
                    }
                }
            }
        }

    }

    /**
     * BeanNameAware 接口实现方法
     * @param name
     */
    public void setBeanName(String name) {
        this.beanName = name;
    }

    /**
     * ApplicationListener实现方法
     * ContextRefreshedEvent bean被装载则会调用
     * @param event
     */
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (this.isDelay() && !this.isExported() && !this.isUnexported()) {
            if (logger.isInfoEnabled()) {
                logger.info("The service ready on spring started. service: " + this.getInterface());
            }

            this.export();
        }

    }

   

    /**
     * InitializingBean
     * 实现方法
     * @throws Exception
     */

    public void afterPropertiesSet() throws Exception {
        Map providerConfigMap;
        /**
         * step1
         * dubbo:servie未指定provider
         *     <dubbo:provider id="test1" delay="-1" retries="0" />
         *     <dubbo:service provider="test1" interface="com.biz.soa.service.seckill.frontend.SoaSeckillFrontService" ref="soaSeckillFrontServiceImpl"/>
         */
        if (this.getProvider() == null) {
            /**
             * step2
             *  BeanFactoryUtils.beansOfTypeIncludingAncestors为获取指定类型以及实现类和子类的集合 key为name
             */
            providerConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, ProviderConfig.class, false, false);
            /**
             * 这里面代码逻辑是混乱的 主要看下面分支吧
             */
            if (providerConfigMap != null && providerConfigMap.size() > 0) {
               Map<String, ProtocolConfig> protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, ProtocolConfig.class, false, false);
                Iterator i$;
                ProviderConfig config;
                /**

                 */
                if ((protocolConfigMap == null || protocolConfigMap.size() == 0) && protocolConfigMap.size() > 1) {
                    List<ProviderConfig> providerConfigs = new ArrayList();
                    i$ = protocolConfigMap.values().iterator();

                    while(i$.hasNext()) {
                        config = (ProviderConfig)i$.next();
                        if (config.isDefault() != null && config.isDefault()) {
                            providerConfigs.add(config);
                        }
                    }

                    if (!providerConfigs.isEmpty()) {
                        this.setProviders(providerConfigs);
                    }
                } else {

                    ProviderConfig providerConfig = null;
                    i$ = protocolConfigMap.values().iterator();
                    label318:
                    /**
                     * step4
                     * 这里面需要注意 要么default为true的放到第一个  要么 非default设置为false 没有缺省值 会报Duplicate provider configs
                     * <dubbo:provider id="test1"  delay="-1" retries="0" />
                     *  <dubbo:provider id="test2" default="true" delay="-1" retries="0" />
                     */
                    while(true) {
                        do {
                            if (!i$.hasNext()) {
                                if (providerConfig != null) {
                                    this.setProvider(providerConfig);
                                }
                                break label318;
                            }

                            config = (ProviderConfig)i$.next();
                            //以上面数据为列 默认null 结束循环  whlie(true) 第二次进来providerConfig不为空 就会报duplicate异常
                        } while(config.isDefault() != null && !config.isDefault());

                        if (providerConfig != null) {
                            throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
                        }

                        providerConfig = config;
                    }
                }
            }
        }

        Iterator i$;
        /**
         * 跟上面逻辑一样 只是是读取application标签
         *  <dubbo:application name="soa-promotion-provider"/>
         */
        if (this.getApplication() == null && (this.getProvider() == null || this.getProvider().getApplication() == null)) {
            protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, ApplicationConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                ApplicationConfig applicationConfig = null;
                i$ = protocolConfigMap.values().iterator();

                label291:
                while(true) {
                    ApplicationConfig config;
                    do {
                        if (!i$.hasNext()) {
                            if (applicationConfig != null) {
                                this.setApplication(applicationConfig);
                            }
                            break label291;
                        }

                        config = (ApplicationConfig)i$.next();
                    } while(config.isDefault() != null && !config.isDefault());

                    if (applicationConfig != null) {
                        throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
                    }

                    applicationConfig = config;
                }
            }
        }

        /**
         * 跟上面一样 读取moudule标签
         * <dubbo:module name="soa-promotion-provider" version="1.0" owner="liqianng" organization="信息部"></dubbo:module>
         */
        if (this.getModule() == null && (this.getProvider() == null || this.getProvider().getModule() == null)) {
            protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, ModuleConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                ModuleConfig moduleConfig = null;
                i$ = protocolConfigMap.values().iterator();

                label270:
                while(true) {
                    ModuleConfig config;
                    do {
                        if (!i$.hasNext()) {
                            if (moduleConfig != null) {
                                this.setModule(moduleConfig);
                            }
                            break label270;
                        }

                        config = (ModuleConfig)i$.next();
                    } while(config.isDefault() != null && !config.isDefault());

                    if (moduleConfig != null) {
                        throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
                    }

                    moduleConfig = config;
                }
            }
        }

        ArrayList protocolConfigs;
        /**
         * 同上
         *  <dubbo:registry address="${zookeeper.url}"   file=".dubbo/promotion-provider.cache" check="false" />
         */
        if ((this.getRegistries() == null || this.getRegistries().isEmpty()) && (this.getProvider() == null || this.getProvider().getRegistries() == null || this.getProvider().getRegistries().isEmpty()) && (this.getApplication() == null || this.getApplication().getRegistries() == null || this.getApplication().getRegistries().isEmpty())) {
            protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, RegistryConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                protocolConfigs = new ArrayList();
                i$ = protocolConfigMap.values().iterator();

                label240:
                while(true) {
                    RegistryConfig config;
                    do {
                        if (!i$.hasNext()) {
                            if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
                                super.setRegistries(protocolConfigs);
                            }
                            break label240;
                        }

                        config = (RegistryConfig)i$.next();
                    } while(config.isDefault() != null && !config.isDefault());

                    protocolConfigs.add(config);
                }
            }
        }

        /**
         *  //表示从注册中心发现监控地址
         *     <dubbo:monitor protocol="registry"></dubbo:monitor>
         */
        if (this.getMonitor() == null && (this.getProvider() == null || this.getProvider().getMonitor() == null) && (this.getApplication() == null || this.getApplication().getMonitor() == null)) {
            protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, MonitorConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                MonitorConfig monitorConfig = null;
                i$ = protocolConfigMap.values().iterator();

                label215:
                while(true) {
                    MonitorConfig config;
                    do {
                        if (!i$.hasNext()) {
                            if (monitorConfig != null) {
                                this.setMonitor(monitorConfig);
                            }
                            break label215;
                        }

                        config = (MonitorConfig)i$.next();
                    } while(config.isDefault() != null && !config.isDefault());

                    if (monitorConfig != null) {
                        throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
                    }

                    monitorConfig = config;
                }
            }
        }
        /**
         * 获取配置的协议信息
         *   <dubbo:protocol register="false"  name="dubbo" port="23888" threadpool="fixed" threads="500" dispatcher="message"/>
         *
         */
        if ((this.getProtocols() == null || this.getProtocols().isEmpty()) && (this.getProvider() == null || this.getProvider().getProtocols() == null || this.getProvider().getProtocols().isEmpty())) {
            protocolConfigMap = this.applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, ProtocolConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                protocolConfigs = new ArrayList();
                i$ = protocolConfigMap.values().iterator();

                label190:
                while(true) {
                    ProtocolConfig config;
                    do {
                        if (!i$.hasNext()) {
                            if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
                                super.setProtocols(protocolConfigs);
                            }
                            break label190;
                        }

                        config = (ProtocolConfig)i$.next();
                    } while(config.isDefault() != null && !config.isDefault());

                    protocolConfigs.add(config);
                }
            }
        }

        if ((this.getPath() == null || this.getPath().length() == 0) && this.beanName != null && this.beanName.length() > 0 && this.getInterface() != null && this.getInterface().length() > 0 && this.beanName.startsWith(this.getInterface())) {
            this.setPath(this.beanName);
        }

        /**
         * 是否延迟注册服务 默认为0  以毫秒为单位
         */
        if (!this.isDelay()) {
            this.export();
        }

    }
    /**
     * 是否延迟加载
     * @return
     */
    private boolean isDelay() {
        //从当前service标签获取
        Integer delay = this.getDelay();
        ProviderConfig provider = this.getProvider();
        //如果没有设置则从provider标签获取
        if (delay == null && provider != null) {
            delay = provider.getDelay();
        }
        return this.supportedApplicationListener && (delay == null || delay == -1);
    }
    /**
     * DisposableBean实现方法
     * @throws Exception
     */
    public void destroy() throws Exception {
    }

}

ServiceConfig

真正服务发布的方法 以下方法 该方法为继承父类ServiceConfig的方法

if (!this.isDelay()) {
            this.export();
        }

猜你喜欢

转载自www.cnblogs.com/LQBlog/p/11972887.html