Refer取得invoker的過程
<!-- 指定了哪種的注冊中心,是基於zookeeper協議的,指定了注冊中心的地址以及端口號 --> <dubbo:registry protocol="zookeeper" client="zkclient" address="localhost:2181"/> <!-- 引用遠程DemoService服務 --> <dubbo:reference id="demoService"interface="com.alibaba.d ubbo.demo.DemoService"/>
Spring加載每個<dubbo:reference/>標簽的時候都會生成一個ReferenceBean。

如上圖,ReferenceBean實現了Spring的FactoryBean接口,實現了此接口的Bean通過Spring的BeanFactory.getBean(“beanName”)獲取的對象不是配置的Bean本身,而是通過FactoryBean.getObject()方法返回的對象,此接口在Spring內部被廣泛使用,用來獲取代理對象等等。這里getObject方法用來生成對遠程服務調用的代理。
1. loadRegistries()獲取配置的注冊中心的registryUrls;
2. 遍歷registryUrls集合,給registryUrl加上refer key,該key就是要引用的遠程服務;
[registry://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.6.1&pid=2484&refer=application%3ddemo-consumer%26dubbo%3d2.6.1%26interface%3dcom.alibaba.dubbo.demo.DemoService%26methods%3dsayHello%26pid%3d2484%26side%3dconsumer%26timestamp%3d1415879965901®istry=dubbo×tamp=1415879990670]
3. 遍歷registryUrls集合,使用Protocol.refer(interface,regist ryUrl)方法refer到可執行對象invoker;
4. 如果注冊中心有多個的話,通過集群策略Cluser.join()將多個invoker偽裝成一個可執行invoker,這里默認使用available策略;
5. 利用代理工廠生成代理對象proxyFactory.getProxy(invoker)。
這里實際上跟export過程類似,通過RegistryProtocol.refer獲得invoker。
RegistryProtocol. Refer過程
1. 根據傳入的registryUrl來選擇RegistryProcol,它的協議屬性是registry,下面要選擇使用哪種注冊中心,所以要根據REGISTRY_KEY屬性重新設置registrUrl;
dubbo://localhost:2181/com.alibaba.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.6.1&pid=4524&refer=application%3Ddemo-consumer%26dubbo%3D2.6.1%26interface%3Dcom.alibaba.dubbo.demo.DemoService%26methods%3DsayHello%26pid%3D4524%26side%3Dconsumer%26timestamp%3D1415881461048×tamp=1415881461113
2. 根據registrUrl利用RegistryFactory獲取注冊器(過程跟暴露服務那邊一樣),這里是zookeeper協議,得到的注冊器是ZookeeperRegistry;
3.構建引用服務的subscribeUrl
consumer://192.168.56.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.6.1&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=8536&side=consumer×tamp=1415945205031
並通過注冊器向注冊中心注冊消費方,這里的category是consumers;
4. 構建目錄服務RegistryDirectory
構建消費者訂閱url,category=providers表示去注冊中心尋找注冊的服務提供者。
consumer://192.158.56.1/com.alibaba.dubbo.demo.DemoService?application=demo-consumer&category=providers,configurators,routers&dubbo=2.6.1&interface=com.alibaba.dubbo.demo.DemoService&methods=sayHello&pid=9692&side=consumer×tamp=1415967547508
向注冊中心訂閱服務提供方,注冊中心根據消費者傳入的url找到匹配的服務提供者url (注意:這里服務提供者沒有設置category,注冊中心對於沒有設置的默認取providers值)
dubbo://192.168.56.1:20882/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.6.1&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=9828&side=provider×tamp=1415968955329
然后注冊中心回調服務消費者暴露的回調接口來對服務提供者的服務進行引用refer,生成對應的可執行對象invoker。服務提供者與服務的消費建立連接。
5. 通過Cluster合並directory中的invokers, 返回可執行對象invoker。
6. ProxyFactory.getProxy(invoker) 創建代理對象返回給業務方使用。
順便說一下,若注冊中心的協議是dubbo協議,注冊者調注冊中心的服務采用的默認集群調用策略是FailOver,選擇一台注冊中心,只有當失敗的時候才重試其他服務器,注冊中心實現也比較簡單不具備集群功能, 如果想要初步的集群功能可以選用BroadcastCluster,它至少向每個注冊中心遍歷調用注冊一遍。
