一、耦 合問題
有些時候我們在進行介面呼叫的時候,比如說一個 push 推播介面,有可能會涉及到不同渠道的推播。以我目前業務場景為例,我做結算後端服務的,會與金蝶財務系統進行互動,那麽我結算後端會涉及到多個結算單型別,如果每一個種型別的結算單都去暴露一個 contoller 介面給前端提供,而且其實對接第三方的介面,有些介面是共通的。
前端涉及到的問題
需要呼叫後端多個 controller,不同介面 傳 不同的參數,如果遇到後端介面修改,會涉及到多個頁面的修改,耦合度很高;
需要對多個按鈕設定許可權配置。
後端涉及到的問題
需要每個業務介面,都去寫一個對接第三方介面的 push 推播方法,無形中增加很多重復的程式碼,耦合度也很高;
如果涉及到第三方服務介面改造,後端介面也需要進行更改,會修改大量程式碼。
二、如何解決
建立對接第三方服務的微服務,暫定為 tps 服務,該服務只作為一個後端微服務,與第三方服務進行對接,並且合理封裝呼叫參數,將公共參數提出進行封裝;
後端其余業務系統對接這個獨立的微服務,比如訂單、結算、供應商系統對接這個服務,由 tps 服務統一提供對接介面,其余服務實作這個 tps 提供的 feign 介面;
業務系統只需要關註 service 層業務的實作,無需處理對接的業務邏輯。
大致的流程圖就是這樣的:
三、具體實作
Tps 服務
Tps 服務暴露為 feign 介面,前端統一透過 Tps 提供的介面進行呼叫。
//對接第三方服務介面
publicinterfaceIKingdeeManagementService {
Boolean push(KingdeePushCO.Request request);
}
Feign 介面實作類:
@Slf4j
@Service
public classKingdeeManagementServiceImplimplementsIKingdeeManagementService{
@Autowired
private ApplicationContext applicationContext;
@Autowired
private KingdeeThirdSettingService kingdeeThirdSettingService;
@Override
public Boolean push(KingdeePushCO.Request request){
KingdeeBusinessPushServiceEnum kingdeePushServiceEnum = KingdeeBusinessPushServiceEnum.getKingdeePushServiceEnumByType(request.getBusinessType());
IKingdeeBusinessPushService kingdeePushService = null;
try {
kingdeePushService = (IKingdeeBusinessPushService) applicationContext.getBean(kingdeePushServiceEnum.getClazz());
} catch (BeansException e) {
log.error("當前型別暫未實作,請聯系開發");
thrownew ServiceException("當前型別暫未實作,請聯系開發");
}
R<Boolean> result = null;
result = kingdeePushService.pushKingdee(request);
returntrue;
}
}
列舉類別定義:
publicenum KingdeeBusinessPushServiceEnum {
private class clazz;
private Integer type;
privateString interFaceName;
KingdeeBusinessPushServiceEnum( class clazz, Integer type, String interFaceName) {
this.clazz = clazz;
this.type = type;
this.interFaceName = interFaceName;
}
RECEIPT_VOUCHER(IJaKingdeeBillClient. class, KingdeeBusinessTypeConstant.RECEIPT_VOUCHER, KingdeeSettingEnum.INTERFACE_TYPE_JA_RECEIPT_VOUCHER.getCode()), ;
}
分別有 clazz、type、interFaceName 內容,
clazz 定義為 feign 介面,業務系統提供的服務介面;
type 代表前端需要傳的參數,不同的 Integer 值代表不同的 feign 介面對映;
interFaceName 第三方介面列舉,表示需要具體呼叫哪個第三方介面。
業務系統
拿 bms 服務舉例說明:繼承 Tps 服務的 feign 介面,重寫 push 方法;
Feign 介面實作,透過 factory 工廠類初始化,不同的 service 實作類;
JaKingdeeFactoryUtil 工廠工具類,獲取工廠例項,這裏其實也可以使用列舉對映,避免以後介面太多,需要寫很多 case when。
JaKingdeeServiceFactory 是個介面,提供方法:
實作上面的介面,透過單例工廠的模式 double check 的模式實作,並且加悲觀鎖,避免一個工作執行緒多次建立工廠例項,SpringContextUtils/getBean/ 獲取 servcie 例項,業務層只需要實作 service 介面,實作不同業務邏輯的 push 推播方法。
四、總結
這是我之前設計的關於介面統一呼叫的流程,當然其實還是包括對接第三方重復呼叫的問題、呼叫結果緩存、呼叫超時解決、失敗降級的一些策略,作為拋磚引玉。
如喜歡本文,請點選右上角,把文章分享到朋友圈
如有想了解學習的技術點,請留言給若飛安排分享
因公眾號更改推播規則,請點「在看」並加「星標」 第一時間獲取精彩技術分享
·END·
相關閱讀:
作者:Lxlxxx
來源:juejin.cn/post/7276261829726191676
版權申明:內容來源網路,僅供學習研究,版權歸原創者所有。如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝!
架構師
我們都是架構師!
關註 架構師(JiaGouX),添加「星標」
獲取每天技術幹貨,一起成為牛逼架構師
技術群請 加若飛: 1321113940 進架構師群
投稿、合作、版權等信箱: [email protected]