1. 程式人生 > >dubbo 服務暴露 路徑問題

dubbo 服務暴露 路徑問題

疑問

配置dubbo的時候看到了一個非常奇怪的配置:

  <dubbo:protocol name="webservice" port="${dubbo.webservice.port}" server="auto"/>
  <dubbo:protocol name="jaxrs" port="${dubbo.webservice.port}" server="auto"/>
  問題1:埠是否重複?
  問題2:jaxrs不在文件中,協議效果是什麼?

開始

spring在容器載入完畢後使用監聽者模式推送event

// package com.alibaba.dubbo.config.spring;
// 在解析dubbo-spring.xml的時候已經載入到了spring容器
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener,// 會接受到推送訊息
 BeanNameAware

public void onApplicationEvent(ApplicationEvent event) {
        if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName()) && this.isDelay() && !this.isExported() && !this.isUnexported()) {
            if (logger.isInfoEnabled()) {
                logger.info("The service ready on spring started. service: " + this.getInterface());
            }
            this.export();  //呼叫父類的方法,是父類
        }

    }

然後進入:ServiceConfig

// package com.alibaba.dubbo.config;
public class ServiceConfig<T> extends AbstractServiceConfig
 protected synchronized void doExport() {
       // 這是一個受spring-容器管理的bean,在這個方法裡,組裝了一個service所需要的
       所有屬性<dubbo:service ......../>
       this.doExportUrls();
    }
private void doExportUrls() {
        List<URL> registryURLs = this.loadRegistries(true);
        Iterator var2 = this.protocols.iterator();

        while(var2.hasNext()) {
            ProtocolConfig protocolConfig = (ProtocolConfig)var2.next();
            if (!ExportHandlers.getInstance().doExportUrlsFilter(protocolConfig, registryURLs)) {
                this.doExportUrlsFor1Protocol(protocolConfig, registryURLs);
            }
        }
    }

下面是一個非常長的方法:
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
	 String name = protocolConfig.getName();
        if (name == null || name.length() == 0) {
            name = "dubbo";  // 預設是dubbo,但是我們是jaxrs,所以往下走
        }
// 省略獲取ref 遠端服務源
port = null;
        Integer port;
        if (!"webservice".equals(protocolConfig.getName()) && !"jaxrs".equals(protocolConfig.getName())) {
            port = protocolConfig.getPort();
        } else {  // 當 是jaxrs 或者webservice協議的時候走這裡,因為一個服務,要麼使用webservice,要麼使用jaxrs,兩者埠不衝突
            port = WebContainer.getInstance().getPortHTTP();
            if (null == port) {
                String httpPort = TomcatConfigParse.getTomcat6HttpPort("HTTP/1.1", "http"); // 預設8080
                if (null != httpPort && httpPort.length() > 0) {
                    port = Integer.parseInt(httpPort);
                }
            }

            if (null == port) {
                port = protocolConfig.getPort();
            }
        }

		//無關程式碼
		Exporter<?> exporter = protocol.export(invoker); // exporter代表一個暴露服務介面
       this.exporters.add(exporter);
}


package com.alibaba.dubbo.rpc.protocol.rest;
public class RestProtocol extends AbstractProxyProtocol

protected <T> Runnable doExport(T impl, Class<T> type, URL url) throws RpcException {
        String addr = url.getIp() + ":" + url.getPort();
        // 省略無關程式碼

        JAXRSServerFactoryBean serverFactoryBean = new JAXRSServerFactoryBean();
        String prefix = ConfigUtils.getProperty("dubbo.restful.basepath"); // 這個引數在dubbo.properties檔案中能夠進行配置
        if (StringUtils.isEmpty(prefix)) {
            prefix = "/rest";
        } else if (prefix.length() == 1) {
            prefix = "";
        }
// 省略建立Endpoint
    }

結論

jaxrs 和webservice不衝突
jaxrs 可以使用rest 協議代替,最終都交給rest協議來完成功能