Filter Pattern 2 (dubbo的实现方式)
2024-10-21 09:12:51
前一篇FilterPattern的范式,基本和Tomcat实现的filter chain是一样的;
这里介绍一下我看完dubbo关于Filter Pattern的实现思路,自己抽象出来的代码,以及理解
相关类的UML图:
可以从上图中看到这里的Invoker
对应原来的Servlet
,这里的Filter
和原来的Filter
只有参数签名上的区别;
Filter
的第一个参数由FilterChain
变成了Invoker
;
Invoker
和原来的Servlet
的函数签名到是一点都没变,可以理解,只是名字不一样,功能性和原来一样(这里起名Invoker是为了和dubbo中的invoker保持一致)
原先的Filter调用链路是有FilterChain来串联起来,现在FilterChain变成了Invoker,可以简单的猜想,现在由Invoker串起Filter调用链路;(这里你肯定想Invoker不是用来执行具体业务逻辑的吗,怎么能串的起Filter调用链路呢,具体可以往后看)
至于是如何串起的,就要看FilterWrapper
和相关Filter
的代码了
public interface Invoker {
Response invoke(Request request);
}
public class HttpInvoker implements Invoker {
@Override
public Response invoke(Request request) {
Response response = new Response();
response.setData( "RESPONSE OF [" + request.getData() + "]");
return response;
}
}
public class FilterWrapper {
private List<Filter> filterList;
public FilterWrapper(List<Filter> filterList) {
this.filterList = filterList;
}
public Invoker buildInvokerChain(final Invoker invoker){
Invoker last = invoker;
//倒序遍历filterList,保证index最小的在最外层执行
for (int i = filterList.size() - 1; i >= 0 ; i--) {
final Invoker next = last;
Filter filter = filterList.get(i);
last = new Invoker() {
//用匿名内部类,把filter包装成invoker,为了方便理解,就没有写成lambda表达式了
@Override
public Response invoke(Request request) {
return filter.invoke(next, request);
}
};
}
return last;
}
}
public class PrintFilter implements Filter {
@Override
public Response invoke(Invoker invoker, Request request) {
System.out.println("PrintFilter: request:" + request.getData());
return invoker.invoke(request);
}
}
public class ModifyDataFilter implements Filter {
@Override
public Response invoke(Invoker invoker, Request request) {
request.setData(request.getData() + " modified by ModifyDataFilter!");
return invoker.invoke(request);
}
}
public class Main {
public static void main(String[] args) {
ArrayList<Filter> filterList = new ArrayList<>();
filterList.add(new ModifyDataFilter());
filterList.add(new PrintFilter());
FilterWrapper filterWrapper = new FilterWrapper(filterList);
Invoker invoker = filterWrapper.buildInvokerChain(new HttpInvoker());
Request request = new Request("hello word!");
Response response = invoker.invoke(request);
System.out.println(response.getData());
}
}
从上面的代码可以看到,实际上是用Invoker的匿名内部类来实现调用链路的串联,就我浅薄的理解,buildInvokerInvokerChain实现的invoker应该算是柯里化
然而这样写Filter Chain有什么优点呢?
- Filter签名参数再也不用带着FilterChain了,Invoker接口单一,更加安全
最新文章
- input 只读不能修改
- Vim的使用方法
- Linux_服务
- Pinyin4Net
- curl http_code状态码 含义
- CSS预处理语言——less与sass的使用
- [LeetCode] Longest Word in Dictionary 字典中的最长单词
- element 给table的个别表格框添加样式 ---重构里面的组件
- maven多个web模块进行合并
- 本周对于java中lamdba表达式与内部进行了学习 ,以下是我在学习就中遇到的问题
- springmvc上传图片《2》
- python语法_注释
- jQuery-3.事件篇---鼠标事件
- php mysql 查询判断周几
- jsapi微信扫一扫
- rem布局注意问题和meta标签
- [转]Python中函数的值传递和引用传递
- bzoj 2167: 公交车站
- WIN7如何替换开机登录画面
- P1712 [NOI2016]区间
热门文章
- AttributeError: module &#39;requests&#39; has no attribute &#39;get&#39; 报错分析
- k8s-分布式系统架构master-worker
- MyCat2 分表分库
- KU060板卡设计资料原理图第636篇:基于FMC的KU060高性能 PCIe 载板
- python 操作配置文件(configparser模块)
- 7.Object
- MongoDB升级
- vim 小记录
- springboot Elasticsearch 实体创建索引设置Date 类型字段失败
- dll帮助类