天天看點

看了同僚寫的代碼,我竟然開始默默的模仿了

作者:三六七

事情是這樣的,目前我正在參與 XXXX 項目的搭建,需要與第三方對接接口。在對方的接口中存在幾個異步通知,為了接口的安全性,需要對接口的參數進行驗簽處理。

為了友善大家對異步通知傳回參數的處理,Z 同僚提出要将該驗簽功能進行統一封裝,到時候大家隻需要關注自己的業務邏輯即可。

Z 同僚選擇的是“自定義參數解析器”的解決方案,接下來我們通過代碼來了解一下。

使用方法非常簡單,隻需要在參數上引入注解就可以了

問題一

看到這,細心的朋友應該會有所疑問:既然這邊用到了自定義的注解,為什麼不用切面來實作,而是使用自定義的參數解析器呢?Very Good!這也是阿Q提出的疑問,同僚說是因為 jackson 的反序列化動作優先級遠高于切面的優先級,是以還沒進入切面就已經報反序列化失敗的錯誤了。

問題二

為什麼在 controller 中注解 @RequestBody 不見了?

要回答這個問題,我們就得了解下HandlerMethodArgumentResolverComposite這個類了,以下簡稱Composite。SpringMVC 在啟動時會将所有的參數解析器放到 Composite 中,Composite 是所有參數的一個集合。當對參數進行解析時就會從該參數解析器集合中選擇一個支援對 parameter 解析的參數解析器,然後使用該解析器進行參數解析。

又因為@RequestBody是以使用的參數解析器RequestResponseBodyMethodProcessor優先級高于我們自定義的參數解析器,是以如果共用會被前者攔截解析,是以為了正常使用,我們需要将@RequestBody 注解去掉。

上邊 Z 同僚的方案已經可以解決該問題了,但是該方案還有兩個不足之處:

需要每一個回調都去建立自己的 controller 層,沒有一個對外的統一入口;

需要在方法上添加自定義注解,侵入性比較強;

是以經過我們的商議,決定摒棄該方案,但是該方案的思想值得我們學習。接下來讓我們分析一下新的解決方案:

業務接口類包含兩個方法:具體業務處理的類型;業務的具體處理方法。

在 Iservice 中做兩個步驟:

在 spring 啟動之後,收集所有的類型為 INotifyService的類并放入map中;

将參數進行處理轉化,并驗簽處理;

此方案提供統一的異步通知入口,把公共的參數處理和驗簽邏輯與業務邏輯剝離。

利用 java 動态加載類的特性,将實作類通過類型進行收集。

利用 java 多态的特性,通過不同的實作類來處理不同的業務邏輯。

看到這,相信大家已經對這兩種實作方案有了一定的了解,大家可以試着在以後的項目中應用一下,體驗一把!

繼續閱讀