Dubbo-服務提供者初始化


服務提供者初始化過程,即ServiceBean 初始化過程 
 
一、解析配置文件
spring在解析配置文件的過程中,會找到dubbo 命名空間對應的handler,DubboNamespaceHandler
 
public class DubboNamespaceHandler extends NamespaceHandlerSupport {

    static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }

    public void init() {
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
    }

}

 


 
 
啟動大致流程
流程如下
  • spring容器啟動
  • ServiceBean初始化
  • 事件發布,執行onApplicationEvent,開始執行ServiceBean暴露export操作
  • 啟動NettyServer
  • 注冊中心服務暴露export
 
二、ServiceBean執行export
當Spring容器處理完<dubbo:service>標簽后,會在Spring容器中生成一個ServiceBean ,服務的發布也會在ServiceBean中完成。不妨看一下ServiceBean的定義
public class ServiceBean<T> extends ServiceConfig<T> 
    implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware {

}

 

而在Spring初始化完成Bean的組裝,會調用InitializingBean的 afterPropertiesSet方法,在Spring容器加載完成,會接收到事件ContextRefreshedEvent,調用ApplicationListener的 onApplicationEvent方法。
public void afterPropertiesSet() throws Exception {
    // 
    if (!isDelay()) {
        // 暴露服務
        export();
    }
}

 

ServiceBean 實現了ApplicationListener接口,實現onApplicationEvent方法,該方法在spring容器啟動完成后“自動”執行
public void onApplicationEvent(ApplicationEvent event) {
    if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
        if (isDelay() && !isExported() && !isUnexported()) {
            if (logger.isInfoEnabled()) {
                logger.info("The service ready on spring started. service: " + getInterface());
            }
            // 
            export();
        }
    }
}  
 
public synchronized void export() {
    // 延時暴露
    if (delay != null && delay > 0) {
        delayExportExecutor.schedule(new Runnable() {
            public void run() {
                // 暴露服務
                doExport();
            }
        }, delay, TimeUnit.MILLISECONDS);
    } else {
        // 直接暴露服務
        doExport();
    }
}

  

protected synchronized void doExport() {
    // 
    checkApplication();
    checkRegistry();
    checkProtocol();
    appendProperties(this);
    checkStubAndMock(interfaceClass);
    if (path == null || path.length() == 0) {
        path = interfaceName;
    }
    doExportUrls();
}

 

private void doExportUrls() {
    List<URL> registryURLs = loadRegistries(true);
    for (ProtocolConfig protocolConfig : protocols) {
        doExportUrlsFor1Protocol(protocolConfig, registryURLs);
    }
}

 

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
    
    //如果不是remote,則暴露本地服務
    if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
        exportLocal(url);
    }    
    // 如果配置不是local則暴露為遠程服務
    if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
        // 如果注冊中心地址不為null
        if (registryURLs != null && registryURLs.size() > 0) {
            for (URL registryURL : registryURLs) {
                url = url.addParameterIfAbsent("dynamic", registryURL.getParameter("dynamic"));
                // 忽略不相干的代碼 ...
                // 通過代理工廠將ref對象轉化成invoker對象
                Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                // 代理invoker對象
                DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
                // 暴露服務
                Exporter<?> exporter = protocol.export(wrapperInvoker);
                // 一個服務可能有多個提供者,保存在一起
                exporters.add(exporter);
            }
        } else {
            Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
            DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);

            Exporter<?> exporter = protocol.export(wrapperInvoker);
            exporters.add(exporter);
        }
    }
}

 

public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    URL url = invoker.getUrl();
    //忽略若干代碼
    //打開服務
    openServer(url);
    optimizeSerialization(url);
    return exporter;
}

 

private void openServer(URL url) {

    String key = url.getAddress();
    boolean isServer = url.getParameter(Constants.IS_SERVER_KEY, true);
    //是否server端
    if (isServer) {
        ExchangeServer server = serverMap.get(key);
        if (server == null) {
            //如果服務不存在,創建服務
            serverMap.put(key, createServer(url));
        } else {
            server.reset(url);
        }
    }
}

 

private ExchangeServer createServer(URL url) {
    //忽略若干代碼
    ExchangeServer server;
    try {
        server = Exchangers.bind(url, requestHandler);
    } catch (RemotingException e) {
        throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);
    }
    return server;
}

 

生成的Adpative

import com.alibaba.dubbo.common.extension.ExtensionLoader;
public class Protocol$Adpative implements com.alibaba.dubbo.rpc.Protocol {
    public void destroy() {
        // 拋出異常,省略
    }
    public int getDefaultPort() {
        // 拋出異常,省略
    }
    // export
    public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws RpcException {
        if (arg0 == null) 
            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
        if (arg0.getUrl() == null) 
            throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
        com.alibaba.dubbo.common.URL url = arg0.getUrl();
        String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
        if(extName == null) 
            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" 
                                            + url.toString() + ") use keys([protocol])");
        Protocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
        return extension.export(arg0);
    }
    public Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws RpcException {
        if (arg1 == null) 
            throw new IllegalArgumentException("url == null");
        com.alibaba.dubbo.common.URL url = arg1;
        String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
        if(extName == null) 
            throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" 
                                            + url.toString() + ") use keys([protocol])");
        Protocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);
        return extension.refer(arg0, arg1);
    }
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM