责任链将多个处理器(处理对象)串联起来,形成一个链条。每个处理器都包含一个指向下一个处理器的引用,处理请求时,处理器可以决定是否处理请求或将其传递给链中的下一个处理器。
场景特点:
- 请求的处理需要通过多个处理器(Filter)
- 每个处理器都能决定是否在自己的节点结束流程
- Filter 需要能够灵活变更,比如新增、删除、更改顺序
责任链模式的结构
基础结构
- IFilterChainArmory 接口,声明与链条结构相关的方法。
- IFilterChain 接口,继承自 IFilterChainArmory 接口。声明处理者的逻辑方法。
- AbstractFilterChain 抽象类,实现 IFilterChain 接口。实现链条结构方法。
- XXXFilterChain 具体处理者实现类,继承抽象类。实现不同处理器的方法逻辑。
public interface ILogicChainArmory {
ILogicChain appendNext(ILogicChain next);
ILogicChain next();
}
public interface ILogicChain extends ILogicChainArmory{
/**
* 过滤器操作逻辑
*/
void doFilter (String userId);
}
public abstract class AbstractLogicChain implements ILogicChain{
private ILogicChain next;
/**
* 在当前责任链的末尾添加下一个责任链节点
*/
@Override
public ILogicChain appendNext(ILogicChain next) {
this.next = next;
return next;
}
/**
* 获取当前逻辑链的下一个逻辑链
*/
@Override
public ILogicChain next() {
return next;
}
}
可以看到 AbstractLogicChain 的实现很有单向链表的风格,维护指向下一个节点的指针,这就使得每一个 Chain 的结尾都可以直接链接另外一个 Chain,满足了灵活更改的需求。
责任链工厂
责任链工厂负责 责任链的节点组装及维护。
维护:在 Spring 下,我们可以充分利用 其 Map 自动注入的特性,自动将实现 IFilterChain 接口的节点自动注入到 Map 中:
private final Map<String, ILogicChain> logicChainGroup;
组装 openFilterChain():依序将处理者通过 appendNext() 链接,最终将链头返回给用户。
到这里为止,我们已经可以在工厂中组装责任链,从责任链头依序处理到尾了。
// 在责任链工厂依据策略组装责任链
IFilterChain filterChain = defaultChainFactory.openFilterChain(strategyId);
// 从第一个节点开始处理
filterChain.doFilter(userId, strategyId);
每个节点要能进行流程终止
用到递归的思想
- 每个处理者通过调用
return next().doFilter(userId)
来调用下一个处理者的处理逻辑 - 当处理者判断可以终止,就直接 return 特定的结果,而不是继续调用 next()
源码中的使用
javax.servlet 包
Filter、FilterChain 接口,及其一系列实现类
同一个 filter 既处理请求,又处理应答,而且处理顺序是反过来的 request 1 2 3 X 3 2 1 response
public interface Filter {
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
......
}
我们用单链表递归式的责任链能够更好的实现