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
相关文章
相关标签/搜索