Spring MVC 根據 controller 層方法入參和返回值動態生成日誌 - 下 :藉助 SpEL 或自定義的方式解析日誌表達式

上一篇文章已經就如何獲取到 controller 層方法的參數和返回值進行了詳細分析,並且封裝了 HandlerMethodPostProcessor 接口以便使用,接下來就實現業務需求:根據 controller 層方法的入參和返回值動態生成日誌。

實現日誌解析

實現思路是這樣的:定義一個註解,註解的 value 爲日誌表達式,HandlerMethodPostProcessor#postProcessorAfterInvoke 方法中判斷 HandlerMethod 是否使用了該註解,使用了就解析其日誌表達式。

日誌需要根據參數和返回值動態生成,所以需要在日誌表達式中提供一種方式能取到兩者的值,這裏提供兩種實現方式:

  1. 自己定義參數和返回值的獲取表達式,在 postProcessorAfterInvoke 方法中解析時再將其替換爲具體值
  2. 使用 SpEL 表達式,需要將參數和返回值添加到 org.springframework.expression.spel.support.EvaluationContext中,並藉助 SpEL 的 API 進行解析

第一種方式需要自己解析日誌表達式,比較複雜,所以我的實現裏只是進行了簡單的取值,也可以對參數和返回值的成員通過 getter 遞歸取值;SpEL 表達式提供了強大而完備的功能,可以進行算數運算,邏輯判斷,也可以獲取其他 bean、java 類、系統參數或項目參數,但對於簡單的日誌表達式可能不需要這麼多的功能,可以按需使用兩種方式。

自定義日誌表達式

表達式的解析規則如下

  • {parName}: {} 內部的內容將被解析,普通單詞將識別爲參數名
  • {$}: $ 符將被認爲返回值
  • {parName.count}: .count 的形式將調用參數 parName 的 getCount 獲得其值
  • {parName.role.name}: .role.name 的形式將調用參數 parName 的 getRole,再繼續調用 Role 的 getName
  • {$.name}: 調用返回值的相應 getter 方法

可以像下面這樣使用:
image.png

HandlerMethodPostProcessor#postProcessorAfterInvoke 解析時只需將 {} 部分替換爲具體值即可。

SpEL 解析日誌

SpEL 可以像如下方式進行使用:
image.png

解析時#$ 獲取到的是方法返回值,#num 將被替換爲參數 num 的值。

代碼說明

image.png

  1. StandardEvaluationContext + SpelExpressionParser + TemplateParserContext 可以用來解析 SpEL 表達式定義的日誌
  2. logExpressionParser.parse 方法將解析自定義的日誌

handleCustomLog 方法中就可以對日誌進行具體的處理。

    private void handleCustomLog(String content, Object result, ServletInvocableHandlerMethod handlerMethod, Object[]
            args) {
    }

完整代碼已上傳 GitHub,可以在 這裏 找到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章