dubbo服務(wù)端暴露的總體流程如下圖所示:

20180312113446.png
首先 ServiceConfig 類拿到對(duì)外提供服務(wù)的實(shí)際類 ref(如:HelloWorldImpl),然后通過 ProxyFactory 類的 getInvoker 方法使用 ref 生成一個(gè) AbstractProxyInvoker 實(shí)例,到這一步就完成具體服務(wù)到 Invoker 的轉(zhuǎn)化。接下來就是 Invoker 轉(zhuǎn)換到 Exporter 的過程。
以dubbo-demo-provider中提供的demo為例,其xml配置文件如下
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!--服務(wù)提供方使用netty4作為協(xié)議發(fā)布工具-->
<dubbo:provider server="netty4"/>
<!-- use multicast registry center to export service -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>
</beans>
spring通過<dubbo:service>進(jìn)行服務(wù)的節(jié)點(diǎn)創(chuàng)建,并創(chuàng)建對(duì)應(yīng)的一個(gè)ServiceBean,在ServiceBean中主要看方法onApplicationEvent(ContextRefreshedEvent event),該方法通過實(shí)現(xiàn)ApplicationListener接口得到,用于當(dāng)ApplicationEvent發(fā)布到 ApplicationContext時(shí),使得這個(gè)bean得到通知
/**
* ApplicationListener接口的方法
* isDelay:延遲加載 && !isExported:服務(wù)沒有暴露 && !isUnexported 服務(wù)沒有反注冊(cè)
* @param event
*/
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();//執(zhí)行服務(wù)暴露
}
}
public synchronized void export() {
if (provider != null) {
if (export == null) {
export = provider.getExport();
}
if (delay == null) {
delay = provider.getDelay();
}
}
if (export != null && !export) {
return;
}
if (delay != null && delay > 0) {
delayExportExecutor.schedule(new Runnable() {//延遲暴露
public void run() {
doExport();
}
}, delay, TimeUnit.MILLISECONDS);
} else {
doExport();
}
}
protected synchronized void doExport() {
/** ......一系列校驗(yàn)與參數(shù)獲取.....*/
doExportUrls();//將ref進(jìn)行發(fā)布
ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
}