前言
在电商,保险,餐饮领域我们经常会遇到比较复杂的业务场景,比如在电商领域的下单业务中,需要根据用户的身份(是否会员),身份等级,商品属性,用户所处的位置属性等走不同的业务分支,不同业务分支的逻辑处理可能各不相同,每个分支的逻辑处理特别多且不固定,在后续产品完善,需求迭代过程中,需要频繁对各条业务线增减或修改。这时候如果我们只是在原有业务代码的基础上堆积木,业务类可能会越来越膨胀,越来越复杂,终成shi山,以至于后期难以维护,难以及时响应业务方需求,这是一个技术人所不能忍受的。在此分享一下如何使用Pipeline模式拆分,解耦这种复杂业务。
Spring源码中用到的责任链
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 执行完所有增强后执行切点方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
// 动态匹配
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 不匹配则不执行拦截器
return proceed();
}
}
else {
// 普通拦截器,直接调用拦截器,比如 ExposeInvocationInterceptor,AspectJAfterAdvice
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 传入this,形成调用链条,如MethodBeforeAdviceInterceptor,会先执行增强方法,再执行后面逻辑
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
Pipeline模式
上面我们说到Pipeline模式是责任链模式的一个变种,下面看看Pipeline的结构
Pipeline为链表结构,包含了头尾节点,当前上下文, 开始-结束方法,对节点的操作方法
public class DefaultOrderPipeLine implements OrderPipeLine {
// public static TransmittableThreadLocal<StopWatch> pipeLineStopWatchTTL = new TransmittableThreadLocal<>();
public OrderContext context;
public OrderHandlerNode head;
public OrderHandlerNode tail;
public DefaultOrderPipeLine(OrderContext context) {
this.context = context;
head = new OrderHandlerNode();
tail = head;
// pipeLineStopWatchTTL.set(new StopWatch("DefaultCastPipeLine"));
}
@Override
public void addFirst(OrderHandler... handlers) {
OrderHandlerNode handlerNode;
for (OrderHandler handler : handlers) {
OrderHandlerNode preNode = head.getNextNode();
handlerNode = new OrderHandlerNode(handler);
handlerNode.setNextNode(preNode);
head.setNextNode(handlerNode);
}
}
每个handler-node包含了对下一个节点的引用,部分代码如下
public class OrderHandlerNode {
private OrderHandler handler;
private OrderHandlerNode nextNode;
public OrderHandlerNode(OrderHandler handler) {
this.handler = handler;
}
public void execute(OrderContext) {
}
}
每个node包含了handler,各个handler之间通过统一上下文handlerContext串联通信
public class OrderContext {
private String skuId;
private String goodsName;
private BigDecimal amount;
}
当触发pipeline的start方法时,handlerContext便会像一艘小船一样在水流中流动执行。上面举例我们只是创建了订单处理的pipeline,而实际真是业务场景在订单创建前可能需要作很多前置性校验,在订单创建后也可能需要作很多后续工作,如此我们可以起多条pipeline来分别处理不同业务。
tomcat和netty中用到的pipeline模式
https://github.com/jekran/order_pipeline
获取,拉下来即可测试,觉得有用的话,就给本文点个赞吧。如喜欢本文,请点击右上角,把文章分享到朋友圈
如有想了解学习的技术点,请留言给若飞安排分享
因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享
·END·
相关阅读:
一张图看懂微服务架构路线 基于Spring Cloud的微服务架构分析 微服务等于Spring Cloud?了解微服务架构和框架 如何构建基于 DDD 领域驱动的微服务? 微服务架构实施原理详解 微服务的简介和技术栈 微服务场景下的数据一致性解决方案 设计一个容错的微服务架构
作者:自由的_鱼
来源:juejin.cn/post/7203993298817384508
版权申明:内容来源网络,仅供学习研究,版权归原创者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
我们都是架构师!
关注架构师(JiaGouX),添加“星标”
获取每天技术干货,一起成为牛逼架构师
技术群请加若飞:1321113940 进架构师群
投稿、合作、版权等邮箱:admin@137x.com