网站首页 > java教程 正文
前言
什么是责任链
责任链是一种设计模式,它让多个对象有机会处理同一个请求,这些对象形成一个链。请求从链的一端开始,逐个传递给链上的对象,直到某个对象处理它或者请求未被处理。这样,发送请求者无需知道哪个对象会处理,实现了发送者与接收者的解耦,增加了系统的灵活性
责任链的常用场景
- 权限与认证系统:在登录认证、权限验证流程中,不同的处理者可以检查用户名密码、验证权限级别、处理单点登录等。请求(如访问资源)沿着责任链传递,直到找到合适的处理器来授权或拒绝访问。
- 日志记录与错误处理:根据日志级别(如DEBUG, INFO, WARNING,
ERROR)或错误类型,不同的处理器负责记录或处理相应的日志信息或异常。开发者可以灵活地插入或移除处理逻辑,而不影响其他日志处理。 - 请求过滤与处理:在Web服务或API网关中,责任链可用于实现一系列预处理任务,如参数校验、请求限流、IP黑名单过滤、会话管理等,每个处理环节关注于特定的验证或转换逻辑。
- 命令与事件处理:在处理一系列可选的或有顺序依赖的命令或事件时,责任链允许按照预定的逻辑顺序尝试执行处理逻辑,直到命令被执行或事件被妥善处理。
- 工作流与审批流程:在企业应用中,审批流程可以设计成责任链,每个节点代表一个审批层级或角色,请求(如报销单)依次经过各个审批节点,直至最终批准或拒绝。
- UI事件处理:在图形界面应用程序中,事件(如鼠标点击、键盘输入)可以通过责任链分发给不同的组件,每个组件决定是否消费此事件,未处理的事件继续传递给链中的下一个组件。
今天给大家的介绍的责任链有点特殊,它是基于Pipeline-Valve模型,这种模型跟常规的责任链模式有点区别
- 每个Pipeline都是有特定的Valve,而且是在管道的最后一个执行,这个Valve叫BaseValve,并且BaseValve是不可删除的;
- 在上层容器的管道的BaseValve中会调用下层容器的管道。
示例图:
如何实现Pipeline-Valve模型
1、定义Valve接口
该接口表示处理链中的单个处理单元。
public interface Valve extends Ordered {
Valve getNextValve();
void setNextValve(Valve next);
void invoke(ValveContext context);
default boolean isBaiscValve() {
return false;
}
}
2、定义抽象valve(可选)
注:定义该抽象valve主要是为了复用
public abstract class AbstractValve implements Valve {
protected Valve nextValve;
@Override
public Valve getNextValve() {
return nextValve;
}
@Override
public void setNextValve(Valve next) {
this.nextValve = next;
}
@Override
public void invoke(ValveContext context) {
doInvoke(context);
if(nextValve!=null){
nextValve.invoke(context);
}
}
public abstract void doInvoke(ValveContext context);
}
3、 定义Pipeline接口
该接口主要用来用于管理Valve的集合,并提供方法来添加Valve、设置特定valve以及启动处理流程。
public interface Pipeline {
void setBasic(Valve valve);
void addValve(Valve valve);
void process(ValveContext context);
}
4、定义Pipeline的默认实现
public class StandardPipeline implements Pipeline {
/**
* 第一个阀门
*/
protected Valve first;
/**
* 最后一个阀门
*/
protected Valve basic;
@Override
public void setBasic(Valve valve) {
validateValve(valve,true);
this.basic = valve;
}
@Override
public void addValve(Valve valve) {
validateValve(valve,false);
if(first == null){
this.first = valve;
valve.setNextValve(basic);
}else{
Valve current = first;
while(current != null){
if(current.getNextValve() == basic){
current.setNextValve(valve);
valve.setNextValve(basic);
break;
}
current = current.getNextValve();
}
}
}
@Override
public void process(ValveContext context) {
if(first != null){
if(context == null){
context = new ValveContext();
}
first.invoke(context);
}
}
public void validateValve(Valve valve,boolean isCheckBasicValve){
Assert.notNull(valve, "valve must not be null");
if(isCheckBasicValve){
Assert.isTrue(valve.isBaiscValve(), "valve must be basic valve");
}
}
}
注: addValue else流程,是为了保证basic阀门一定是在流程最后被调用
5、定义具体valve
@Component
public class FirstValve extends AbstractValve {
@Override
public void doInvoke(ValveContext context) {
String requestId = "lybgeek-" + UUID.randomUUID().toString();
System.out.println("第一道阀门: requestId-->【" + requestId + "】");
Map<String,Object> request = context.getRequest();
request.put("source",FirstValve.class.getSimpleName());
context.setRequest(request);
context.setRequestId(requestId);
}
@Override
public int getOrder() {
return 1;
}
}
其他阀门类似,就不列举了
6、通过Pipeline 驱动valve
public class PipelineMainTest {
public static void main(String[] args) {
Pipeline pipeline = new StandardPipeline();
pipeline.setBasic(new BasicValve());
pipeline.addValve(new FirstValve());
pipeline.addValve(new SecondValve());
pipeline.addValve(new ThirdValve());
pipeline.process(new ValveContext());
}
}
总结
如果大家对tomcat有了解的话,就会知道本文的实现其实就是tomcat的pipeline-valve的简化版实现。其次上文pipeline驱动valve的步骤可以托管给spring,文末demo链接的代码,有做了相应实现,感兴趣的朋友,可以点击文末链接查看
demo链接
https://github.com/lyb-geek/springboot-learning/tree/master/springboot-pipeline-valve
猜你喜欢
- 2024-12-23 新疆军区某边防团河源边防连采访见闻
- 2024-12-23 还在自己实现责任链?我建议你造轮子之前先看看这个开源项目
- 2024-12-23 风雪边关!一起走近新疆军区某边防团河源边防连
- 2024-12-23 基于Sentinel自研组件的系统限流、降级、负载保护最佳实践探索
- 2024-12-23 入连!授枪! 授枪仪式上连长的讲话
- 2024-12-23 MapStruct架构设计 mapstruct-processor
- 2024-12-23 # 利刃出鞘_Tomcat 核心原理解析(三)
- 2024-12-23 责任链 + 工厂 + 模板方法 + 享元 模式结合业务 - 实践
- 2024-12-23 Spring 框架底层用到的设计模式都有哪些?
- 2024-12-23 go-struct 责任链dutychain 责任链模式实例
你 发表评论:
欢迎- 04-27微服务部署架构设计详解(图文全面总结)
- 04-27Java微服务架构选型与对比:一场技术流派的巅峰对决
- 04-27微服务架构下Java的最佳实践
- 04-27Java微服务架构选型:优雅拆分与高效整合
- 04-27微服务架构下的Java代码拆分策略:像拼图一样构建系统
- 04-27微服务架构下的Java最佳实践
- 04-27微服务架构下Java的挑战与机遇
- 04-27微服务架构下Java事务管理的艺术
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)