本文最后更新于 2025年7月28日 下午
责任链模式将处理请求的对象连城一条链,沿着这条链传递该请求,直到有一个对象处理请求为止,这使得多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
角色
- 抽象处理者 : 定义一个请求处理的接口
- 具体处理者 :实现处理请求的接口,可以选择自己处理或者传递给下一个接收者。包含对下一个接收处理者的引用。
优点
- 解耦请求发送者与接收者 ,便于扩展与复用
- 链结构灵活 ,可以动态添加、移除处理节点
- 增强封装性 ,每个处理器专注于自身逻辑
缺点
- 请求可能得不到处理 (若链尾未处理)
- 调试困难 ,请求流转链路不清晰时可能增加定位成本
- 性能问题 ,链过长或处理器逻辑复杂时可能影响效率
场景
数据流转处理,如敏感词过滤、输入校验、日志处理等
权限校验链、责任审批流程等需要动态组合处理链的场景
实现责任链模式
基础实现 :
- 定义拦截器接口 (filter)
- 定义拦截器实现类 (xxxfilter)
- 创建拦截器容器,装载所有拦截器对象。
- 遍历容器中的对象,执行拦截方法。
- 每个拦截方法都对请求体进行处理,处理后将修改写入请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public interface Filter{ void doFilter(Request request); }
public class HtmlFilter implements Filter{ @Override public void doFilter(Request request){ String msg = request.getMsg(); msg = msg.replaceAll("<","["); msg = msg.replaceAll(">","]"); request.setMsg(msg); } }
public class SensitiveFilter implements Filter{ @Override public void doFilter(Request request){ String msg = request.getMsg(); msg = msg.replaceAll("hit","*"); request.setMsg(msg); } }
public class MsgProcessor{ List<Filter> filters = new ArrayList<>();
public void addFilter(Filter filter){ filters.add(filter); }
public void process(Request request){ for(Filter filter:filters){ filter.doFilter(request); } } }
public class Test{ public static void main(String[] args){ Request request = new Request(""); MsgProcessor msgProcessor = new MsgProcessor(); msgProcessor.addFilter(new HtmlFilter()); msgProcessor.addFilter(new SensitiveFilter()); msgProcessor.addFilter(new FaceFilter()); msgProcessor.process(request); String newMsg = request.getMsg(); System.out.println(newMsg); } }
|
增强
当一个业务流程中存在多个拦截器时,可以通过定义一个chain对象来对一组拦截器进行统一管理。
这时需要进行的定义 :
- 定义一个FilterChain对象 ,其中包含一个容器对象用于存储拦截器对象,一个添加方法
- 为保持一致性,实现filter接口,允许将FilterChain对象添加到容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public class FilterChain{ List<Filter>filters = new ArrayList<>(); public void addFilter(Filter filter){ filters.add(filter); } @Override public void doFilter(Request request){ for(Filter filter:filters){ filter.doFilter(request); } } }
public class MsgProcessor{ private FilterChain filterChain; public void setFilterChain(FilterChain filterChain){ this.filterChain = filterChain ; } public void process(Request request){ filterChain.doFilter(request); } }
public class Client{ public static void main(String[] args){ Request request = new Request("msg"); MsgProcessor msgProcessor = new MsgProcessor(); FilterChain filterChain = new FilterChain(); filterChain.addFilter(new HtmlFilter()); filterChain.addFilter(new SensitiveFilter());
FilterChain filterChain2 = new FilterChain(); filterChain2.addFilter(new FaceFilter()); filterChain.addFilter(filterChain2); msgProcessor.setFilterChain(filterChain); msgProcessor.process(request); String newMsg = request.getMsg(); System.out.println(newMsg); } }
public class FilterChain implements Filter{ List<Filter>filters = new ArrayList<>();
@Override public void doFilter(Request request){ for(Filter filter:filters){ filter.doFilter(request); } } }
|
因为 filterchain 已经具备了 filter的管理和调用能力,所以去除MsgProcessor,改为由filterchain 管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Client2 { public static void main(String[] args){ Request request = new Request("msg"); FilterChain filterChain = new FilterChain(); filterChain.addFilter(new HtmlFilter()); filterChain.addFilter(new SensitiveFilter());
FilterChain filterChain2 = new FilterChain(); filterChain.addFilter(new FaceFilter()); filterChain.doFilter(request); String newMsg = request.getMsg(); System.out.println(newMsg); } }
|
双向拦截
在上述功能实现后,可以通过添加一个Response来对最终相应的数据进行处理。
- 定义Response 类
- 将response 参数添加到Filter的doFilter中
- 向相关的方法中添加response对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| public class Response { private String msg ; public Response(String msg){ this.msg = msg ; }
public String getMsg(){ return msg ; }
public void setMsg(String msg){ this.msg = msg ; } }
public interface Filter{ void doFilter(Request request , Response response); }
public class SensitiveFilter implements Filter{ @Override public void doFilter(Request request , Response response){ String msg = request.getMsg(); msg = msg.replaceAll("hit","*"); request.setMsg(msg);
response.setMsg(response.getMsg()+"-SensitiveFilter"); } }
@Override public void doFilter(Request request , Response response){ for(Filter filter : filters ){ filter.doFilter(request,response); } }
public class Client2{ public static void main(String[] args){ Request request = new Request("msg"); Response response = new Response("I love you");
FilterChain filterChain = new FilterChain(); filterChain.addFilter(new HtmlFilter()); filterChain.addFilter(new SensitiveFilter()); FilterChain filterChain2 = new FilterChain(); filterChain2.addFilter(new SensitiveFilter()); filterChain2.addFilter(filterChain2);
filterChain.doFilter(request,response); String newMsg = request.getMsg(); System.out.println(newMsg); System.out.println(response.getMsg()); } }
|
在添加后在doFilter中 具备两个对象可以被拦截器操作。
通过遍历执行所有拦截器的doFilter方法,其调用链如下:
1 2 3 4 5 6 7 8
| Client - FilterChain.doFilter() - FilterChain.doFilter.doFilter(); - FilterChain.doFilter.doFilter.HtmlFilter(); - FilterChain.doFilter.doFilter.SensitiveFilter(); - ... -
|
当我们需要在 正向处理 请求的解码过程,逆向处理响应的编码过程时,需要通过嵌套调用doFilter方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Client - FilterChain.doFiler() - FilterChain.doFilter.resolve_request1() -FilterChain.doFilter() - FilterChain.doFilter.resolve_request2() - FilterChain.doFilter() - FilterChain.doFilter.resolve_request3() - FilterChain.doFilter.resolve_response3() - - FilterChain.doFilter.resolve_response2() - - FilterChain.doFilter.resolve_response1() -
|
修
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public void doFilter(Request request , Response response , FilterChain filterChain){ String msg = request.getMsg(); msg = msg.replaceAll("<","["); msg = msg.replaceAll(">","]"); request.setMsg(msg);
filterChain.doFilter(request,response,filterChain);
response.setMsg(reponse.getMsg()+"-HtmlFilter"); }
public class FilterChain implements Filter{ List<Filter>filters = new ArrayList<>(); private int index = 0 ;
public void addFilter(Filter filter){ filters.add(filter); }
@Override public void doFilter(Request request , Response response , FilterChain filterChain){ if(index == filters.size()) return ; Filter filter = filters.get(index); index++; filter.doFilter(request,response,filterChain); } }
|
责任链模式
责任链模式是一种非常实用的行为型设计模式,它天然适用于“流水线”式的处理流程,尤其在框架级别的请求预处理、响应后处理机制中广泛使用。通过链式结构实现灵活组合、解耦与扩展,使得系统处理流程更加可控、可组合、可扩展。