文章目录
1.责任链模式的应用
- Apache Tomcat 对 Encoding 编码处理的处理
- SpringBoot ⾥⾯的拦截器、过滤器链
- netty 中的处理链
- 支付风控的机制
- ⽇志处理级别
2.责任链模式的代码实践
2.1 方式一
public class OrderContext {
/**
* 请求唯一序列ID
*/
private String seqId;
/**
* 用户ID
*/
private String userId;
/**
* 产品skuId
*/
private Long skuId;
/**
* 下单数量
*/
private Integer amount;
/**
* 用户收货地址ID
*/
private String userAddressId;
//..set、get
}
数据处理接口OrderHandleIntercept
public interface OrderHandleIntercept {
/**
* 指定执行顺序
* @return
*/
int sort();
/**
* 对参数进行处理
* @param context
* @return
*/
OrderAddContext handle(OrderAddContext context);
}
分别创建三个不同的接口实现类, 并指定顺序
- RepeatOrderHandleInterceptService:用于重复下单的逻辑验证
- ValidOrderHandleInterceptService:用于验证请求参数是否合法
- BankOrderHandleInterceptService:用于检查客户账户余额是否充足
@Component
public class RepeatOrderHandleInterceptService implements OrderHandleIntercept {
@Override
public int sort() {
//用于重复下单的逻辑验证,在执行顺序为1
return 1;
}
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("通过seqId,检查客户是否重复下单");
return context;
}
}
@Component
public class ValidOrderHandleInterceptService implements OrderHandleIntercept {
@Override
public int sort() {
//用于验证请求参数是否合法,执行顺序为2
return 2;
}
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("检查请求参数,是否合法,并且获取客户的银行账户");
return context;
}
}
@Component
public class BankOrderHandleInterceptService implements OrderHandleIntercept {
@Override
public int sort() {
//用于检查客户账户余额是否充足,在执行顺序为3
return 3;
}
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("检查银行账户是否合法,调用银行系统检查银行账户余额是否满足下单金额");
return context;
}
}
创建一个订单数据验证管理器OrderHandleChainService, 管理实现类
@Component
public class OrderHandleChainService implements ApplicationContextAware {
private List<OrderHandleIntercept> handleList = new ArrayList<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//获取指定的接口实现类,并按照sort进行排序,放入List中
Map<String, OrderHandleIntercept> serviceMap = applicationContext.getBeansOfType(OrderHandleIntercept.class);
handleList = serviceMap.values().stream()
.sorted(Comparator.comparing(OrderHandleIntercept::sort))
.collect(Collectors.toList());
}
/**
* 执行处理
* @param context
* @return
*/
public OrderAddContext execute(OrderAddContext context){
for (OrderHandleIntercept handleIntercept : handleList) {
context =handleIntercept.handle(context);
}
return context;
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class CalculatorServiceTest {
@Autowired
private OrderHandleChainService orderHandleChainService;
@Test
public void test(){
orderHandleChainService.execute(new OrderAddContext());
}
}
通过seqId,检查客户是否重复下单
检查请求参数,是否合法,并且获取客户的银行账户
检查银行账户是否合法,调用银行系统检查银行账户余额是否满足下单金额
也可以通过如下方式进行手动add排序。
@Component
public class OrderHandleChainService {
private List<OrderHandleIntercept> handleList = new ArrayList<>();
@Autowired
private ValidOrderHandleInterceptService validOrderHandleInterceptService;
@Autowired
private RepeatOrderHandleInterceptService repeatOrderHandleInterceptService;
@Autowired
private BankOrderHandleInterceptService bankOrderHandleInterceptService;
@PostConstruct
public void init(){
//依次手动add对象
handleList.add(repeatOrderHandleInterceptService);
handleList.add(validOrderHandleInterceptService);
handleList.add(bankOrderHandleInterceptService);
}
/**
* 执行处理
* @param context
* @return
*/
public OrderAddContext execute(OrderAddContext context){
for (OrderHandleIntercept handleIntercept : handleList) {
context =handleIntercept.handle(context);
}
return context;
}
}
2.2 方式二
通过注解@Order来指定排序
/**
* 指定注入顺序为1
*
*/
@Order(1)
@Component
public class RepeatOrderHandleInterceptService implements OrderHandleIntercept {
//...省略
}
/**
* 指定注入顺序为2
*
*/
@Order(2)
@Component
public class ValidOrderHandleInterceptService implements OrderHandleIntercept {
//...省略
}
/**
* 指定注入顺序为3
*
*/
@Order(3)
@Component
public class BankOrderHandleInterceptService implements OrderHandleIntercept {
//...省略
}
2.3 方式三
通过定义抽象类来实现责任链设计模式
AbstractOrderHandle.java
public abstract class AbstractOrderHandle {
/**
* 责任链,下一个链接节点
*/
private AbstractOrderHandle next;
/**
* 执行入口
* @param context
* @return
*/
public OrderAddContext execute(OrderAddContext context){
context = handle(context);
// 判断是否还有下个责任链节点,没有的话,说明已经是最后一个节点
if(getNext() != null){
getNext().execute(context);
}
return context;
}
/**
* 对参数进行处理
* @param context
* @return
*/
public abstract OrderAddContext handle(OrderAddContext context);
public AbstractOrderHandle getNext() {
return next;
}
public void setNext(AbstractOrderHandle next) {
this.next = next;
}
}
创建三个处理类,并排好序号
@Order(1)
@Component
public class RepeatOrderHandle extends AbstractOrderHandle {
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("通过seqId,检查客户是否重复下单");
return context;
}
}
@Order(2)
@Component
public class ValidOrderHandle extends AbstractOrderHandle {
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("检查请求参数,是否合法,并且获取客户的银行账户");
return context;
}
}
@Order(3)
@Component
public class BankOrderHandle extends AbstractOrderHandle {
@Override
public OrderAddContext handle(OrderAddContext context) {
System.out.println("检查银行账户是否合法,调用银行系统检查银行账户余额是否满足下单金额");
return context;
}
}
责任链管理器: OrderHandlerManager
@Component
public class OrderHandleManager {
@Autowired
private List<AbstractOrderHandle> orderHandleList;
@PostConstruct
public void init(){
//如果List没有按照@Order注解方式排序,可以通过如下方式手动排序
Collections.sort(orderHandleList, AnnotationAwareOrderComparator.INSTANCE);
int size = orderHandleList.size();
for (int i = 0; i < size; i++) {
if(i == size -1){
orderHandleList.get(i).setNext(null);
} else {
orderHandleList.get(i).setNext(orderHandleList.get(i + 1));
}
}
}
/**
* 执行处理
* @param context
* @return
*/
public OrderAddContext execute(OrderAddContext context){
context = orderHandleList.get(0).execute(context);
return context;
}
}
测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class CalculatorServiceTest {
@Autowired
private OrderHandleManager orderHandleManager;
@Test
public void test(){
orderHandleManager.execute(new OrderAddContext());
}
}
通过seqId,检查客户是否重复下单
检查请求参数,是否合法,并且获取客户的银行账户
检查银行账户是否合法,调用银行系统检查银行账户余额是否满足下单金额
















