责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。
什么是责任链模式?
责任链模式的核心思想是将多个对象组成一条链,并沿着这条链传递请求,直到有一个对象能够处理该请求。每个对象都有自己的处理逻辑以及对下一个处理者的引用,当收到请求后,它可以选择自行处理或者将请求传递给下一个处理者。
SpringCloud Gateway 中责任链的使用
在上篇文章中记录了 SpringCloud Gateway中过滤器使用了适配者模式,其实当所有过滤器适配处理之后,会把所有的过滤器传给一个过滤器链 DefaultGatewayFilterChain(FilteringWebHandler类中的内部静态类),并通过滤器链执去行过滤逻辑,如下:
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
private final int index;
private final List<GatewayFilter> filters;
DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
this.index = 0;
}
private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
this.filters = parent.getFilters();
this.index = index;
}
public List<GatewayFilter> getFilters() {
return filters;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
// 执行过滤链
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
return filter.filter(exchange, chain);
}
else {
return Mono.empty(); // complete
}
});
}
}
责任链模式+适配者模式+工厂模式 结合spring使用例子
参考网关逻辑,实现过滤逻辑
定义过滤器接口和实现
/**
* 过滤接口对象
*
* @author LGC
*/
public interface MyFilter {
void filter(ChainExchange exchange, FilterChain filterChain);
}
/**
* @author LGC
*/
@Component
public class AMyFilter implements MyFilter, Ordered {
@Override
public void filter(ChainExchange exchange, FilterChain filterChain) {
System.out.println("A filter order 1 do");
filterChain.filter(exchange);
}
@Override
public int getOrder() {
return 1;
}
}
/**
* @author LGC
*/
@Component
public class BMyFilter implements MyFilter, Ordered {
@Override
public void filter(ChainExchange exchange, FilterChain filterChain) {
System.out.println("B filter order 2 do");
filterChain.filter(exchange);
}
@Override
public int getOrder() {
return 2;
}
}
/**
* @author LGC
*/
@Component
public class CMyFilter implements MyFilter {
@Override
public void filter(ChainExchange exchange, FilterChain filterChain) {
System.out.println("C filter no order do");
filterChain.filter(exchange);
}
}
定义过滤器实现排序接口适配器
/**
* 适配器
* 转换成排序的过滤器
*
* @author LGC
*/
public class OrderedMyFilterAdapter implements MyFilter, Ordered {
private final MyFilter delegate;
private final int order;
public OrderedMyFilterAdapter(MyFilter delegate, int order) {
this.delegate = delegate;
this.order = order;
}
@Override
public void filter(ChainExchange exchange, FilterChain filterChain) {
this.delegate.filter(exchange, filterChain);
}
@Override
public int getOrder() {
return this.order;
}
}
定义过滤器链数据交换中心
/**
* 过滤链交换信息 可保存一下过滤器需要的一些信息
*
* @author LGC
*/
public interface ChainExchange {
void put(Object key, Object value);
<T> T get(Object key);
@Nullable
ApplicationContext getApplicationContext();
}
/**
* 默认链条数据交换
*
* @author LGC
*/
public class DefaultChainExchange implements ChainExchange {
@Nullable
private final ApplicationContext applicationContext;
private final Map<Object, Object> attributes = new ConcurrentHashMap<>();
public DefaultChainExchange(@Nullable ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void put(Object key, Object value) {
attributes.put(key, value);
}
@Override
public <T> T get(Object key) {
return (T) attributes.get(key);
}
@Override
public ApplicationContext getApplicationContext() {
return this.applicationContext;
}
}
工厂方法模式创建过滤链
/**
* 过滤器链工厂
*
* @author LGC
*/
public interface FilterChainFactory {
FilterChain create();
}
/**
* @author LGC
*/
public abstract class AbstractFilterChainFactory implements FilterChainFactory, ApplicationContextAware {
private ApplicationContext applicationContext;
private List<MyFilter> filters = new ArrayList<>();
@Override
public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
// 在容器进行属性赋值后,执行 aware 相关回调
this.applicationContext = applicationContext;
}
/**
* 加载所有过滤器
*
* @return
*/
public List<MyFilter> loadFilter() {
if (filters.size() > 0) {
return filters;
}
Collection<MyFilter> values = applicationContext.getBeansOfType(MyFilter.class).values();
filters = values.stream().map(filter -> {
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
return new OrderedMyFilterAdapter(filter, order);
}
return filter;
}).collect(Collectors.toList());
return filters;
}
}
/**
* @author LGC
*/
@Component
public class MyFilterChainFactory extends AbstractFilterChainFactory {
@Override
public FilterChain create() {
// 从容器中加载所有的过滤器
List<MyFilter> filters = loadFilter();
// 排序 摘自 gateway 网关 FilteringWebHandler -> DefaultGatewayFilterChain
// 这个可过滤需要执行的handler 逻辑
AnnotationAwareOrderComparator.sort(filters);
return new MyFilterChain(filters);
}
}
/**
* @author LGC
*/
public interface FilterChain {
/**
* @param exchange 过滤链数据交换
*/
void filter(ChainExchange exchange);
}
/**
* 过滤器
* 参考 Gateway GatewayFilterChain
*
* @author LGC
*/
public class MyFilterChain implements FilterChain {
/**
* 所有过滤器
*/
private final List<MyFilter> filters;
/**
* 当前过滤器下标
*/
private final Integer index;
public MyFilterChain(List<MyFilter> filters) {
this.filters = filters;
this.index = 0;
}
private MyFilterChain(MyFilterChain parent, Integer index) {
this.filters = parent.getFilters();
this.index = index;
}
public List<MyFilter> getFilters() {
return filters;
}
@Override
public void filter(ChainExchange exchange) {
if (this.index < filters.size()) {
MyFilter myFilter = filters.get(index);
myFilter.filter(exchange, new MyFilterChain(this, this.index + 1));
} else {
System.out.println("过滤链执行完毕....");
}
}
}
测试
/**
* @author LGC
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LaboratoryApplication.class)
public class MyFilterChainPatternTest {
@Resource
private FilterChainFactory filterChainFactory;
@Resource
private ApplicationContext applicationContext;
@Test
public void chainTest() {
// 构建过滤链交换器,用于过滤器直接存储数据用
ChainExchange chainExchange = new DefaultChainExchange(applicationContext);
// 工厂创建过滤链-把过滤器从容器中获取-并进行排序
FilterChain filterChain = filterChainFactory.create();
filterChain.filter(chainExchange);
}
}
// 输出
// A filter order 1 do
// B filter order 2 do
// C filter no order do
// 过滤链执行完毕....
**上面只完成了简单的拦截链逻辑,其实我们调用完过滤链后,可以定义执行我们具体的业务逻辑。假如有一个会员卡支付扣除余额并通知的业务,过滤链则可以是支付前各种复杂的校验,过滤链执行通过后,执行会员卡扣除余额等一系列操作则为具体的业务逻辑。修改一下我们的实现:
升级
修改过滤链和过滤器实现
主要是加了一个参数 Consumer consumer, 用作过滤链执行后操作逻辑
/**
* 过滤器
* 参考 Gateway GatewayFilterChain
*
* @author LGC
*/
public class MyFilterChain implements FilterChain {
/**
* 所有过滤器
*/
private final List<MyFilter> filters;
/**
* 当前过滤器下标
*/
private final Integer index;
public MyFilterChain(List<MyFilter> filters) {
this.filters = filters;
this.index = 0;
}
private MyFilterChain(MyFilterChain parent, Integer index) {
this.filters = parent.getFilters();
this.index = index;
}
public List<MyFilter> getFilters() {
return filters;
}
@Override
public void filter(ChainExchange exchange, Consumer<ChainExchange> consumer) {
if (this.index < filters.size()) {
MyFilter myFilter = filters.get(index);
myFilter.filter(exchange, new MyFilterChain(this, this.index + 1), consumer);
} else {
System.out.println("过滤链执行完毕....");
consumer.accept(exchange);
}
}
}
/**
* @author LGC
*/
@Component
public class AMyFilter implements MyFilter, Ordered {
@Override
public void filter(ChainExchange exchange, FilterChain filterChain, Consumer<ChainExchange> consumer) {
System.out.println("A filter order 1 do 校验1");
filterChain.filter(exchange, consumer);
}
@Override
public int getOrder() {
return 1;
}
}
// 其它修改类....
定义支付业务处理Handler
采用模版方法设计模式,统一入口执行过滤链,和执行具体支付逻辑
/**
* 订单处理handler
*
* @author LGC
*/
public interface OrderHandler {
void handle(ChainExchange chainExchange);
}
/**
* 模版方法设计模式
*
* @author LGC
*/
public abstract class AbstractOrderHandler implements OrderHandler {
@Override
public void handle(ChainExchange chainExchange) {
// 执行过滤链
FilterChainFactory factory = chainExchange.get(FilterChainFactory.class);
FilterChain filterChain = factory.create();
filterChain.filter(chainExchange, this::onHandle);
}
/**
* 执行过滤链后具体逻辑 handle
*
* @param chainExchange
*/
public abstract void onHandle(ChainExchange chainExchange);
}
/**
* 订单支付handler
*
* @author LGC
*/
@Component
public class OrderPayHandler extends AbstractOrderHandler {
@Override
public void onHandle(ChainExchange chainExchange) {
//chainExchange.get(OrderInfo.Class)
System.out.println("获取订单信息,完成订单支付逻辑...");
//
}
}
升级后测试
通过支付handler执行支付流程
/**
* @author LGC
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LaboratoryApplication.class)
public class MyFilterChainPatternTest {
@Resource
private FilterChainFactory filterChainFactory;
@Resource
private ApplicationContext applicationContext;
@Resource
private OrderHandler orderHandler;
@Test
public void chainTest() {
// 构建过滤链交换器,用于过滤器直接存储数据用
ChainExchange chainExchange = new DefaultChainExchange(applicationContext);
chainExchange.put(FilterChainFactory.class, filterChainFactory);
orderHandler.handle(chainExchange);
// 发送通知
}
}
// 输出
// A filter order 1 do 校验1
// B filter order 2 do 校验2
// C filter no order do
// 过滤链执行完毕....
// 获取订单信息,完成订单支付逻辑...
从输出结果可知,当执行完过滤链后,会执行订单支付的逻辑。其实还有很多优化的地方,比如下单可以有很多种支付方式,不同商品类目可能只支持某些支付方式,我们可以通过适配者模式,找出商品类目所支持的支付方式,再根据下单时选择的支付方式,获取适配的支付Handler执行支付。同时我们也可以加入重试机制,不同的支付方式可以配置不同的重试策略,所有可以优化的地方点还有很多
结语
责任链模式能够降低请求发送者和接收者之间的耦合度,使得系统更灵活、可扩展