背景介紹:
A服務(wù)是基礎(chǔ)服務(wù)同衣,靠一個appid做省份的隔離竟块,這個appid需要調(diào)用方設(shè)置請求頭傳入,一般情況是前端請求耐齐,用戶的數(shù)據(jù)自然可以得知省份浪秘;
B服務(wù)做統(tǒng)計的業(yè)務(wù),需要從A服務(wù)讀取數(shù)據(jù)埠况。這個調(diào)用完全是后端之間的服務(wù)調(diào)用耸携,所以需要自己設(shè)置appid的請求頭。同時舊的結(jié)構(gòu)是沒做省份隔離的辕翰,所以需要讀所有省份的數(shù)據(jù)合并返回與舊的返回結(jié)果結(jié)構(gòu)相同夺衍,才能兼容舊的代碼。
實現(xiàn)
一開始想用代理模式喜命,不過這樣會需要改動原來的業(yè)務(wù)代碼沟沙,又想到每個請求的結(jié)構(gòu)類似,所以抽象出如下的代碼:
- 把a(bǔ)ppid設(shè)置在配置文件里面
- 模版
@Slf4j
public abstract class AbstractItemsUomClientTemplate<T extends BaseVo> {
public abstract void checkParam();
public abstract T call();
public abstract String getErrorMsgTitle();
public final T execute(List<String> appIdList) {
if(CollectionUtils.isEmpty(appIdList)) {
return null;
}
checkParam();
List<T> voList = new ArrayList<>();
appIdList.stream().forEach(appId -> {
try {
XXXXXContext.setSdpAppId(appId);
T vo = call();
if (vo != null && CollectionUtils.isNotEmpty(vo.getItems())) {
voList.add(vo);
}
} catch (Exception e) {
log.error(getErrorMsgTitle(),e);
}
});
if(CollectionUtils.isEmpty(voList)) {
return null;
}
// 把每個省份的數(shù)據(jù)合并
return (T) merge(voList);
}
}
- 使用:
把請求頭的部分提取出來壁榕,下次再寫的時候矛紫,只需要關(guān)注業(yè)務(wù)調(diào)用,省份的隔離變得無感知了
public XXX getXXXXXByXXXX(......) {
// ...
XXX xxx = new AbstractItemsUomClientTemplate<XXX>() {
@Override
public void checkParam() {
// 校驗
}
@Override
public XXX call() {
// 在這里調(diào)用A服務(wù)
}
@Override
public String getErrorMsgTitle() {
return "....";
}
}.execute(appIdConfig.getList());
return xxx;
}
總結(jié)
適用于結(jié)構(gòu)類似的方法牌里,抽象出來颊咬,方便維護(hù)和擴(kuò)展