说明:
- 整个责任链上Filter处理器的执行通过处理器自驱进行实现,而非由责任链对象驱动 。
- Filter处理器的在处理过程中除了执行自我逻辑,会通过filterChain.doFilter
(servletRequest, servletResponse)触发下一个处理器的执行 。
![开源框架中的责任链模式实践](http://img.jiangsulong.com/230928/15451I945-3.jpg)
文章插图
- Dubbo的Filter作用时机如上图所示,Filter实现是专门为服务提供方和服务消费方调用过程进行拦截,Dubbo本身的大多功能均基于此扩展点实现 , 每次远程方法执行该拦截都会被执行 。
- Dubbo官方针对Filter做了很多的原生支持,目前大致有20来个吧,包括我们熟知的RpcContext,accesslog功能都是通过filter来实现了 。
- 在实际业务开发中会对Filter接口进行扩展,在服务调用链路中嵌入我们自身的处理逻辑 , 如日志打印、调用耗时统计等 。
@Activate(group = PROVIDER, value = https://www.isolves.com/it/cxkf/kj/2023-09-28/ACCESS_LOG_KEY)public class AccessLogFilter implements Filter {@Overridepublic Result invoke(Invoker> invoker, Invocation inv) throws RpcException {try {if (ConfigUtils.isNotEmpty(accessLogKey)) {AccessLogData logData = buildAccessLogData(invoker, inv);log(accessLogKey, logData);}} catch (Throwable t) {}// 执行下一个invokerreturn invoker.invoke(inv);}}
说明:- Dubbo中的自定义Filter需要实现org.Apache.dubbo.rpc.Filter类,内部通过实现invoke方法来实现自定义逻辑 。
- 自定义Filter内部除了实现必要的自定义逻辑外,核心的需要通过invoker.invoke(inv)触发下一个过滤器的执行 。
public class ProtocolFilterWrapper implements Protocol {private final Protocol protocol;public ProtocolFilterWrapper(Protocol protocol) {this.protocol = protocol;}private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {// 最后的 Invoker 对象Invoker<T> last = invoker;// 遍历所有 Filter 对象,构建责任链List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);if (!filters.isEmpty()) {for (int i = filters.size() - 1; i >= 0; i--) {// 每个 Filter 封装成一个 Invoker 对象,通过 filter.invoke进行串联final Filter filter = filters.get(i);final Invoker<T> next = last;last = new Invoker<T>() {@Overridepublic Result invoke(Invocation invocation) throws RpcException {return filter.invoke(next, invocation);}};}}return last;}}// 封装了Filter的invoker对象static final class ProtocolFilterWrapper.1 implements Invoker < T > {final Invoker val$invoker;final Filter val$filter;// 指向下一个Invoker的变量final Invoker val$next;public Result invoke(Invocation invocation) throws RpcException {return this.val$filter.invoke(this.val$next, invocation);}ProtocolFilterWrapper.1(Invoker invoker, Filter filter, Invoker invoker2) {this.val$invoker = invoker;this.val$filter = filter;this.val$next = invoker2;}}
说明:- ProtocolFilterWrapper通过
buildInvokerChain构建Dubbo Filter的责任链 。 - 责任链上的处理器对象是将Filter封装的Invoker对象,每个Invoker对象指向下一个处理器封装的Invoker对象 。
public class FailfastClusterInvoker<T> extends AbstractClusterInvoker<T> {public FailfastClusterInvoker(Directory<T> directory) {super(directory);}@Overridepublic Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {checkInvokers(invokers, invocation);Invoker<T> invoker = select(loadbalance, invocation, invokers, null);try {// 执行封装了Filter的invoker对象,驱动处理器的执行return invoker.invoke(invocation);} catch (Throwable e) {}}}static final class ProtocolFilterWrapper.1 implements Invoker < T > {final Invoker val$invoker;final Filter val$filter;final Invoker val$next;public Result invoke(Invocation invocation) throws RpcException {return this.val$filter.invoke(this.val$next, invocation);}ProtocolFilterWrapper.1(Invoker invoker, Filter filter, Invoker invoker2) {this.val$invoker = invoker;this.val$filter = filter;this.val$next = invoker2;}
说明:- 每个Invoker对象invoke方法会执行自定义逻辑,并触发下一个处理器的执行 。
推荐阅读
- CORS 跨域资源共享在Spring Boot中的实现
- Java面试题之SpringBoot 框架
- 一文读懂Spring框架中的不同类型事件
- RouterSploit:一款功能强大的嵌入式设备渗透测试框架
- 校友眼中的李雪琴是个“怪人”,内耗严重,父母离婚是病因!
- 杨梅核能吞吗?杨梅核吞入胃中的好处
- 杭州电子厂老板,25年来待客只用“假茅台”,行家:高手中的高手
- 筱在名字中的寓意是什么
- 薛平贵中的西凉是哪里 西凉是哪里
- 祭祀之礼是指 祭祀之礼是指五礼中的