SpringMVC一種新的攔截機制-風格鏈

處理器攔截器詳解——跟着開濤學SpringMVC 程序員,你還不會合理選擇Filter、Interceptor、Aspect?html

簡介

同一個系統中不一樣的接口,均可以分紅幾種獨特的類型,好比某些接口都是作確認交易的,某些接口都是作結果交易的,咱們把這種類似性叫作接口的風格,如Rapping中的不一樣風格(Style),因此咱們給那些具備相同風格的接口以聲明註解的方式來肯定該接口的Style,而在對應的Style中有經過責任鏈的機制來控制通用業務代碼的執行時機,兩者結合起來就叫作風格鏈(Style Chains)java

也能夠把它簡單理解爲SpringMVC中實現請求攔截的一種新方式。 風格鏈是爲了簡化攔截器的編寫,預期以優雅的業務代碼封裝、抽象、共用,從而實現標準的、簡化的開發流程。

首先提醒一點,咱們應該避免「濫用」風格鏈,以免出現責任鏈模式可能帶來的負效應,如:git

  • 系統性能將受到必定影響,並且在進行代碼調試時不太方便,可能會形成循環調用。
  • 可能不容易觀察運行時的特徵,有礙於除錯。

核心攔截器

自定義業務風格器自己就是基於SpringMVC的攔截器來進行擴展:程序員

  • 經過StyleHandlerInterceptor來實現攔截器各個鉤子的時機捕獲

風格鏈

  • 在不一樣的鉤子中判斷是否具備Style 的註解,若是有則調用並執行
  • 在攔截的對應Stylechains字段,安裝不一樣的鉤子調用不一樣的類IChain集合,而且有順序的規則
  • IChain它抽出了3個接口,分別對應攔截器的3個方法,即:
  • 應用端經過實現不一樣的接口來標示性的具備對應時機的處理能力,如:
package cn.jiiiiiin.business.style.validator;


import cn.jiiiiiin.mvc.common.exception.MVCException;
import cn.jiiiiiin.mvc.common.style.chain.annotaion.Validator;
import cn.jiiiiiin.mvc.common.style.chain.impl.IValidator;
import cn.jiiiiiin.mvc.common.utils.MVCUtil;
import cn.jiiiiiin.validate.code.ValidateCodeProcessor;
import cn.jiiiiiin.validate.code.ValidateCodeProcessorHolder;
import cn.jiiiiiin.validate.code.dict.ValidateCodeDict;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

/** * 驗證碼驗證邏輯,直接配置在網關完成,當前類只是作一個{@link IValidator}的示例 * * @author jiiiiiin */
@Validator
@AllArgsConstructor
@Deprecated
public class BusImageCodeValidator implements IValidator {

  /** * 系統中的校驗碼處理器 */
  private final ValidateCodeProcessorHolder validateCodeProcessorHolder;

  @Override
  public boolean validate(HttpServletRequest request, HttpServletResponse response, Object handler) throws MVCException {
    val imageCode = MVCUtil.getData(ValidateCodeDict.DEFAULT_PARAMETER_NAME_CODE_IMAGE);
    ValidateCodeProcessor validateCodeProcessor;
    if (StringUtils.isNotEmpty(imageCode)) {
      validateCodeProcessor = validateCodeProcessorHolder.findValidateCodeProcessor("image");
    } else {
      validateCodeProcessor = validateCodeProcessorHolder.findValidateCodeProcessor("sms");
    }
    validateCodeProcessor.validate(new ServletWebRequest(request, response));
    return true;
  }
}
複製代碼

上面實現了一個通用的圖形驗證碼校驗器,這一塊代碼實際上是能夠被共用的,由於圖形驗證碼須要在進入到控制器對於接口以前被執行,故咱們這裏集成了IValidator,定義完畢以後,咱們就能夠在須要的地方使用它,如:web

@ApiOperation(value = "行內轉帳結果", notes = "行內轉帳結果", httpMethod = "POST")
  @PostMapping("/account/transfer/inner/InnerTransfer/Submit")
  // @ResStyle
  @Style(chains = {BusImageCodeValidator.class})
  public InnerTransferSubmitVo.Res innerTransferSubmit( @RequestBody @Validated InnerTransferSubmitVo.Req req) {
    innerTransferSvc.innerTransferSubmit(req);
    InnerTransferSubmitVo.Res res = ReflectUtil.newInstance(InnerTransferSubmitVo.Res.class);
    return res;
  }
複製代碼

@Style(chains = {BusImageCodeValidator.class})便可以在某一個接口,如行內轉帳結果接口spring

  • 如何讓代碼更簡潔,讓業務抽象更明確?

能夠看到上面有一行註釋的代碼@ResStyle,咱們看看它作了什麼:apache

@Documented
@Target({METHOD})
@Style
@Retention(RUNTIME)
public @interface ResStyle {

  Class<? extends IChain>[] chains() default {BusImageCodeValidator.class, BusLogCompletion.class};
}
複製代碼

這是一個結果交易業務風格註解,在chains中覆蓋了@Style註解的同名成員變量,在其中聲明瞭一個圖形驗證碼校驗器,一個流水日誌環繞記錄器。 這樣咱們就把結果交易須要完成的重複性業務代碼給抽取出來了。mvc

  • 最後咱們能夠看到圖形驗證碼校驗器上面聲明瞭一個@Validator註解,它是什麼? app

    1. @Override相似他們是一個語義化註解,在不一樣的Bus Style實現組件上面表明這個類所要完成的工做,StyleHandlerInterceptor中會以這一組註解爲依據,調用@Style中具備對應功能的組件集合的確切方法,也就是說若是你的組件implements IValidator那麼這個組件就必須聲明成@Validator組件,不然default boolean validate(HttpServletRequest request, HttpServletResponse response, Object handler)接口將不會被執行,這也是爲了經過強約束,來強化這種約定因爲配置的設計。
    2. 能夠看到每個註解都有何其對應的一個Interface,如@Chain->IChain
    3. 另外爲了簡化代碼編寫和提升語義化,每個風格鏈註解都聲明瞭一個#Component,這樣的好處就是,被咱們的風格鏈註解註釋的組件,都會默認加入到Spring的IOC容器中

系統風格鏈組件列表

系統中定義的類IChain,每一個組件都須要更新到這裏以便進行檢索ide

組件 功能 模塊
BusImageCodeValidator 驗證碼驗證邏輯 business-common

系統風格鏈註解列表

系統中定義的類@Chain,每一個註解都須要更新到這裏以便進行檢索

組件 功能 模塊
ResStyle 結果交易通用註解 business-common
相關文章
相關標籤/搜索