SpringBoot如何使用责任链模式实现参数校验

后端 潘老师 5个月前 (12-07) 204 ℃ (0) 扫码查看

本文主要讲解关于SpringBoot如何使用责任链模式实现参数校验相关内容,让我们来一起学习下吧!

概念:

责任链模式是一种行为设计模式,它允许多个对象都有机会处理请求,而不是将请求发送给一个处理者。每个处理者都包含对下一个处理者的引用,形成一个链条。请求沿着这条链传递,直到有一个处理者处理它为止。

如果有对责任了模式不懂的同学可以阅读文章《责任链模式Java案例实现及应用场景详解

使用场景:

  1. 多个对象可以处理同一请求: 当一个请求可以被多个对象中的一个处理,而不确定哪个对象会处理,就可以使用责任链模式。
  2. 请求的发送者和接收者解耦: 发送者不需要知道处理请求的具体对象,只需将请求发送给第一个处理者。接收者也不需要知道请求的发送者是谁,只需处理请求即可。
  3. 动态组合处理者: 可以动态地组合和拆解处理者链。通过增加或移除处理者,可以灵活地调整系统的处理流程。
  4. 避免请求发送者与接收者耦合: 请求发送者无需知道处理请求的具体处理者,从而降低了系统的耦合度。
  5. 处理请求的对象集合可能会变动: 处理者链可以动态地调整,适用于对象集合可能变动的情况。

缺点:

  1. 性能问题: 因为责任链的请求可能被多个处理者依次处理,直到找到合适的处理者为止,可能会导致一定的性能开销。
  2. 请求可能无法被处理: 如果责任链没有被正确配置,或者存在漏洞,可能导致请求无法被处理。
  3. 可能过于灵活: 过度使用责任链模式可能导致系统变得过于灵活,难以理解和维护。

建议:

其实看了以上缺点之后我们可以发现,对于一些不必要的场景我们尽量还是不要去使用责任链模式来给系统增加复杂度,对于后期接手项目的同学是相当的难以维护及理解,当然这里的同学指的是像我这种菜鸡程序员。

案例Demo:

下面我就基于请求参数处理的需求来实现一个简单的Spingboot下开发的一个Demo案例,我处理过程中是对对象中的参数count进行规则判断进行加减

第一步是先创建出责任链处理的接口和请求参数实体对象

/**责任链节点的接口
 */
public interface Handler  {
    /**
     * 节点处理请求接口
     * @param request
     */
    void handleRequest(HandlerRequest request);

    /**
     * 设置下一个节点处理者
     * @param nextHandler
     */
    void setNextHandler(Handler nextHandler);
}
/** 请求参数实体
 */
public class HandlerRequest {
    private Integer count;

    public HandlerRequest(Integer count) {
        this.count = count;
    }

    public HandlerRequest() {
    }

    public Integer getCount() {
        return count;
    }

    public void setContent(Integer count) {
        this.count = count;
    }
}

第二步则是根据业务去定义相对应的处理接口实现类

@Slf4j
public class FirstHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("first handler");
        if (request.getCount() <= 2) {
            request.setContent(request.getCount() + 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}
@Slf4j
public class SecondHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("second handler");
        if (request.getCount() > 2) {
            request.setContent(request.getCount() + 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}
@Slf4j
public class ThirdHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("third handler");
        if (request.getCount() < 5) {
            request.setContent(request.getCount() - 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}

第三步便是最关键的一步,编写责任链配置中心去管理我们需要的处理规则实现类

/**责任链配置管理中心
 */
@Configuration
public class ChainConfig {

    @Bean
    public Handler chain() {
        FirstHandler firstHandler = new FirstHandler();
        SecondHandler secondHandler = new SecondHandler();
        ThirdHandler thirdHandler = new ThirdHandler();
        //这里填写顺序没有强制要求
        firstHandler.setNextHandler(secondHandler);
        secondHandler.setNextHandler(thirdHandler);

        return firstHandler;
    }
}

最后便是我们的测试接口了

/** 责任链测试接口
 */
@Slf4j
@RestController
@Api(tags = "责任链测试接口")
@RequestMapping("/responsibility")
public class HandlerController {

    @Resource
    private Handler handler;

    @ApiOperation("测试接口")
    @GetMapping("/test")
    public void handleRequest(){
        HandlerRequest request = new HandlerRequest(1);
        handler.handleRequest(request);
        log.info("success , count : "+request.getCount());
    }
}

测试结果

注意

这里测试结果是没问题的,这里需要大家注意下,我的这个Demo里的handler实现是在配置中心中手动new创建出来的,并不是利用spring相关注解进行实例化,所以大家参考的时候要注意,如果在上面加上spring的@Service等注解,项目会无法启动,报错信息是发现多个handler实例。

这里欢迎大家对我提出宝贵的建议,我自身对这个责任链模式的使用并不是很熟练,也没有在项目中实践过,如果大家有更好的案例欢迎评论出来,我会去学习的!

以上就是关于SpringBoot如何使用责任链模式实现参数校验相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/12199.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】