-
消費者端dubbo的yml配置
dubbo: consumer: timeout: 300000 protocol: name: dubbo port: -1 cloud: subscribed-services: order-server # subscribed-services: hello-server,account-server,storage-server,order-server
-
按住ctrl + 鼠標左擊
subscribed-services
如下圖: -
這里是對應的setter方法,上面找到定義地方:
/** * All services of Dubbo. */ public static final String ALL_DUBBO_SERVICES = "*"; /** * The subscribed services, the default value is "*". The multiple value will use * comma(",") as the separator. * * @see #ALL_DUBBO_SERVICES */ private String subscribedServices = ALL_DUBBO_SERVICES;
讀一讀就知道答案了。默認為*,多個值時候用
,
隔開。
接下來,走走最表面的流程,就是看看怎么處理我們輸入的數據的,至於是怎么找到提供者的,先不管。
-
光標點到類
DubboCloudProperties
上面,這里ctrl+單擊是點不進去的,但是你點一下有提醒:No usages found in Project Files Press Ctrl+Alt+F7 again to search in 'Project and Libraries
-
跟着提醒,Ctrl+Alt+F7,如果提醒關閉了,就雙擊F7,出來下圖。
-
直接回車,就是高亮的這一行。回去復制
ubscribedServices
,不要開頭的s,不管大寫還是小寫,Ctrl+F搜出來看看。 -
通過點擊向上向下的箭頭,或者F3(下一個)/Shift+F3(上一個)來讀一讀源碼。這里我們看到他在237行時候進行了初始化。
-
老樣子,ctrl+單擊
initSubscribedServices()
方法。讀一下,如果
ALL_DUBBO_SERVICES
等於我們輸入的提供者,就是輸出巴拉巴拉。 -
那么
ALL_DUBBO_SERVICES
是啥,ctrl點,發現又跳回第一個文件了:@ConfigurationProperties(prefix = CONFIG_PROPERTY_PREFIX) public class DubboCloudProperties { /** * All services of Dubbo. */ public static final String ALL_DUBBO_SERVICES = "*"; // 這里是默認為*,如果set方法沒有執行,那么get時候獲得的就是* private String subscribedServices = ALL_DUBBO_SERVICES; /* ... */ }
#### **現在測試一下輸出那個東西,啟動一個提供者,然后消費者訂閱的提供者寫成`*`或者注釋掉。啟動消費者。**
查看日志:
```txt
2021-05-27 16:28:24.950 WARN 6564 --- [client.listener] a.c.d.m.r.DubboServiceMetadataRepository : Current application will subscribe all services(size:20) in registry, a lot of memory and CPU cycles may be used, thus it's strongly recommend you using the externalized property 'dubbo.cloud.subscribed-services' to specify the services
```
與步驟8中一致。
-
接着讀else,如果我們填入內容了,就
subscribedServices()
后加入到那個集合中newSubscribedServices.addAll(dubboCloudProperties.subscribedServices());
ctrl點
subscribedServices()
,然后發現又轉到第一個文件了:再繼續讀一下:使用
commaDelimitedListToStringArray
將我們輸入的東西轉化了字符串數組,處理返回。 -
我們來看看
commaDelimitedListToStringArray
怎么處理的,找到導入它的地方:import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
然后ctrl點:
/** * Convert a comma delimited list (e.g., a row from a CSV file) into an * array of strings. * @param str the input {@code String} (potentially {@code null} or empty) * @return an array of strings, or the empty array in case of empty input */ public static String[] commaDelimitedListToStringArray(@Nullable String str) { return delimitedListToStringArray(str, ","); }
這里與標題3.中
The multiple value will use comma(",") as the separator.
對應。 -
結論:
- 不寫或者*會訂閱所有的。
- 寫多就使用
,
隔開。
參考:Dubbo配合SpringBoot,實現接口多個實現(group)
yml文件的dubbo部分與平時沒有兩樣
(這是提供者和消費者都是自己的情況,如果分開就是scan
和registry
加上面是提供者,cloud
加上面的是消費者(不包括scan和registry))
dubbo:
consumer:
retries: 5
protocol:
port: -1
name: dubbo
scan: #將那個目錄下的文件上nacos作為提供者
base-packages: com.example.service.impl
registry: #注冊中心
address: nacos://127.0.0.1:8848
cloud: #訂閱提供者
subscribed-services: my-application
只是在提供者的實現方法1的注解@Service
后添加組,代碼如下:
package com.example.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
@Service(group = "service1")
public class TestServiceOneImpl implements TestService {
/* ... */
}
提供者的實現方法2的注解@Service
后也添加組,代碼如下:
package com.example.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
@Service(group = "service2")
public class TestServiceOneImpl implements TestService {
/* ... */
}
在消費者端使用時候,同樣注解@Reference
后面添加組,代碼如下:
package com.example.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Reference(group = "service1")
private TestService testServiceOne;
@PostMapping("/test")
public String testMethod() {
testServiceOne...
return null;
}
}
至此就可以指定同接口提供的不同實現類接口了。
若接口是泛型定義的,也即不確定參數或者返回類型,那么在定義接口時候使用TestService<T>,實現類可以指定實現類型方式 implements TestService<MyOwnClass>這個泛型接口是與分組不沖突的。
擴展:
關於DubboReference和DubboService這兩個注解。