先來看咱們的provider.xml的配置文件spring
這個文件的重要性確定重要,那麼這些標籤是怎麼來的呢?api
其實就是spring自定義標籤來的,在源碼中咱們能夠看到,緩存
繼續看spring.handlers文件中內容app
能夠看得出這個DubboNamespaceHandler應該很重要,最後能夠找出他的所在位置,同時還發現同目錄下還有DubboBeanDefinitionParser相似於spring中BeanDefinitionParser。DubboNamespaceHandler相似於spring中NamespaceHandler:ide
再進去看看裏面到底作了些什麼東東函數
能夠看到ui
DubboBeanDefinitionParser繼承spring的BeanDefinitionParser,DubboNamespaceHandlerSupport繼承spring的NamespaceHandlerSupport,NamespaceHandlerSupport繼承NamespaceHandler。由此能夠知道這個provider.xml配置文件的解析其實就是和spring同樣解析。url
在這個spring目錄下咱們看到這兩個類spa
這兩個類很是重要:debug
ServiceBean服務端發佈入口
ReferenceBean客戶端發佈入口
先看看服務端的服務是怎麼發佈的
他是實現spring的這幾類來作的。因此仍是基於spring來作的
這個類中afterPropertiesSet()方法中。是否延遲加載
export()方法就是作了一些參數校驗
無論是否延遲加載都會走doExport()方法,doExport()方法也是作一些參數校驗 和配置項的校驗
而後調用doExportUrls()
就是在provider.xml中配置多個protocol
doExportUrlsFor1Protocol中 1:使用各類方法獲取本地ip 2:若是沒有配置端口則
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
獲取默認端口dubbo默認20880
3:拼湊url
dubbo://192.168.11.1:20880/com.tian.dubbo.IGpHello?anyhost=true&application=hello-world-app&default.delay=10&delay=10&dubbo=2.5.6&generic=false&interface=com.tian.dubbo.IGpHello&methods=sayHello&pid=121964&side=provider×tamp=1529758790987
而後
debug到此
這裏有個Invoker對象爲
因此咱們能夠把Invoker對象理解爲服務的代理對象。
若是沒有配置註冊中心,
protocol
----->Protocol$Adaptive
---->ProtocolFilterWrapper(ProtocolListenerWrapper(DubboProtocol))。底層是基於netty協議去啓動一個nettyserver
} else {//若是沒有配置註冊中心 Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url); Exporter<?> exporter = protocol.export(invoker);//dubbo exporters.add(exporter); }
Protocol extension = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(「registry」);
registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
protocol=RegistryProtocol
RegistryProtocol的export方法源碼
doLocalExport()本地發佈
對緩存進行雙重檢查鎖,若是有就直接返回,不然new一個
debug到此,相關屬性對應的值:
exporter相關屬性
此時相關值
上面
一樣根據
Protocol extension =ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(「dubbo」);
protocol=DubboProtocol.這裏並非得到一個單純的DubboProtocol擴展點,而是會經過Wrapper對Protocol進行裝飾,裝飾器分別爲: ProtocolFilterWrapper/ ProtocolListenerWrapper;兩個裝飾類的源碼爲如下:
這個類很是重要,dubbo機制裏面日誌記錄、超時等等功能都是在這一部分實現的
這個類有3個特色,
第一它有一個參數爲Protocol protocol的構造函數;
第二,它實現了Protocol接口;
第三,它使用責任鏈模式,對export和refer函數進行了封裝;部分代碼以下,上面的源碼中ProtocolFilterWrapper有個buildInvokderChain()方法
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { //buildInvokerChain函數:它讀取全部的filter類,利用這些類封裝invoker
|
咱們看以下文件:
/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter
其實就是對Invoker,經過以下的Filter組裝成一個責任鏈
echo=com.alibaba.dubbo.rpc.filter.EchoFilter |
這其中涉及到不少功能,包括權限驗證、異常、超時等等,固然能夠預計計算調用時間等等應該也是在這其中的某個類實現的;這裏其實就是dubbo中AOP
這裏咱們能夠看到export和refer過程都會被filter過濾
在這裏咱們能夠看到export和refer分別對應了不一樣的Wrapper;export是對應的ListenerExporterWrapper。這塊暫時先不去分析,由於這個地方並無提供實現類。
debug到此
exporterMap
createServer方法()
Exchangers.bind()方法
這裏使用的是getExchange(url)=默認自適應擴展類HeaderExchanger
這裏先去Transporters.bind()方法,
getTransporter().bind(url, handler);
這裏的自適應擴展類就是默認的netty的
構造一個NettyServer
繼續調用父類的方法
這個open()方法在這個父類裏並無實現,而是採用模板方法模式,由各自實現類本身去實現
到此本地發佈已經結束。