基于双向责任链的接口设计
Posted kuailefangyuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于双向责任链的接口设计相关的知识,希望对你有一定的参考价值。
基于双向责任链的接口设计
基于双向责任链的接口特点如下:
1、一个完整的接口由基于LinkedList的filterChain责任链组实现,filterChain包括多个公共业务filter和最终业务处理handler,而handler本身也是filter。
2、每个filter包括process()往后处理和onPostProcess()回调,责任链先调用process()正向单向执行。责任链执行到最后一个节点-Handler业务处理完毕后,再依次调用OnPostProcess()回调方法,回溯反向执行责任链,从而实现单向链表的逆向回调,即所谓的双向责任链。
3、filter节点之间通过ProcessContext上下文对象来存储责任链过程中的相关参数,如request、response对象等。
双向责任链的执行流程如下图所示:
1、正向调用接口IProcessFilter
/**
* 责任链调用接口
*/
public interface IProcessFilter
/**
* 链节点的处理
* 1、当前节点需要持有链表FilterChain以继续调用后续链的执行
* 2、同时需要持有上个节点传递过来的回调对象,以执行完后回调到上个节点的后处理流程。
* @param processContext
* @param filterChain
* @param callback
* @throws InterruptedException
* @throws ProcessException
*/
public void process(ProcessContext processContext, IFilterChain filterChain, IFilterCallback callback) throws InterruptedException, ProcessException;
2、回调接口IFilterCallback
/**
* 责任链回调接口
*/
public interface IFilterCallback
/**
* 回调,因为是下个节点直接调用,除上下文外无需多余参数
* @param context
* @throws ProcessException
*/
public void onPostProcess(ProcessContext context) throws ProcessException;
3、ProcessContext业务执行上下文
/**
* 业务执行上下文
*/
@Getter
@Setter
public class ProcessContext
/**
* 请求原文
*/
private String jsonRequest;
/**
* 请求
*/
private BaseRequest<? extends BaseResponse> request;
/**
* 响应
*/
private BaseResponse response;
/**
* 应答原文
*/
private String jsonResponse;
/**
* 处理业务
*/
private BusinessService businessService;
/**
* 服务开始时间
*/
private long startServiceTime = System.currentTimeMillis();
/**
* 服务结束时间
*/
private long endServiceTime;
public ProcessContext(String jsonRequest)
this.jsonRequest = jsonRequest;
4、双向责任链IFilterChain接口及实现
/**
* 责任链
* 只需持有处理上下文、回调对象即可
*/
public interface IFilterChain
void process(ProcessContext processContext, IFilterCallback callback) throws ProcessException, InterruptedException;
/**
* 基于LinkedList的双向责任链
*/
public class LinkedFilerChain implements IFilterChain
private LinkedList<IProcessFilter> filters;
public LinkedFilerChain(LinkedList<IProcessFilter> filters)
this.filters = filters;
/**
* 执行责任链
* @param processContext
* @param callback
* @throws ProcessException
*/
@Override
public void process(ProcessContext processContext, IFilterCallback callback) throws ProcessException, InterruptedException
assert this.filters != null && !this.filters.isEmpty();
// 从第一个filter开始执行
IProcessFilter processFilter = this.filters.removeFirst();
processFilter.process(processContext, this, callback);
5、业务处理抽象基类AbstractServiceHandler定义
/**
* 抽象serviceHandler基类
*/
public abstract class AbstractServiceHandler implements IProcessFilter
@Override
public void process(ProcessContext processContext, IFilterChain filterChain, IFilterCallback callback) throws ProcessException
/**
* 注意这里handle处理因为是责任链最后一个节点,只需执行回调即可,无需持有filterChain
*/
handle(processContext, callback);
abstract public void handle(ProcessContext processContext, IFilterCallback callback) throws ProcessException;
以添加用户接口AddUserServiceHandler为例:
public class AddUserServiceHandler extends AbstractServiceHandler
@Override
public void handle(ProcessContext processContext, IFilterCallback callback) throws ProcessException
log.info("添加用户开始");
try
Thread.sleep(100L);
catch (InterruptedException e)
e.printStackTrace();
log.info("添加用户结束");
// 设置响应内容
AddUserRequest req = (AddUserRequest) processContext.getRequest();
AddUserResponse resp = (AddUserResponse)processContext.getResponse();
resp.setErrCode("SUCCESS");
resp.setErrMsg("添加用户成功");
resp.setUserName(req.getUserName());
resp.setAge(req.getAge());
// 此处为一个完整服务正向责任链的执行终点,此处执行回调,逆向执行责任链
callback.onPostProcess(processContext);
6、完整定义接口业务BusinessService
一个完整的接口业务BusinessService包括如下:
1、请求request报文,返回响应response报文
2、公共业务处理filters
3、具体业务处理ServiceHandler
4、业务执行,执行双向责任链filterChain (filters+serviceHandler)
public class BusinessService
private IRequest request;
private IResponse response;
@Setter
@Getter
private BaseRequest<? extends BaseResponse> requestPrototype;
/**
* 前处理filters
*/
private List<IProcessFilter> filterTemplate;
/**
* 最终处理serviceHandler
*/
private AbstractServiceHandler businessHandler;
/**
* 执行一个完整的业务
*/
public void execute(ProcessContext processContext, IFilterCallback callback) throws ProcessException, InterruptedException
log.info("开始处理业务请求: ", System.nanoTime());
processContext.setBusinessService(this);
// 构建责任链
LinkedList<IProcessFilter> filters = new LinkedList<>();
filters.addAll(this.filterTemplate);
filters.add(businessHandler);
LinkedFilerChain filterChain = new LinkedFilerChain(filters);
// 执行双向责任链
try
filterChain.process(processContext, callback);
finally
log.info("完成业务处理", System.nanoTime());
6、接口示例
以下以添加用户接口AddUserService为示例:
1、添加用户请求报文AddUserRequest
2、执行责任链
具体执行顺序如下:
- JsonConvertFilter
- checkRequestTimeFilter
- AddUserServiceHandler
3、返回添加用户响应报文AddUserResponse
Spring容器配置xml文件配置addUserService接口如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="jsonConvertFilter" class="com.fymei.filter.JsonConvertFilter" />
<bean id="checkRequestTimeFilter" class="com.fymei.filter.CheckRequestTimeFilter" />
<util:list id="addUserFilters">
<ref bean="jsonConvertFilter" />
<ref bean="checkRequestTimeFilter" />
</util:list>
<bean id="addUserService" class="com.fymei.framework.BusinessService">
<property name="requestPrototype">
<bean class="com.fymei.jsonbean.AddUserRequest" />
</property>
<property name="filterTemplate" ref="addUserFilters"/>
<property name="businessHandler">
<bean class="com.fymei.service.AddUserServiceHandler"/>
</property>
</bean>
</beans>
AddUserService接口的执行测试如下:
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/application-context.xml")
public class TestAddUser
@Qualifier("addUserService")
@Autowired
private BusinessService addUserService;
@org.junit.Test
public void test() throws InterruptedException, ProcessException
// 构建请求报文
AddUserRequest req = new AddUserRequest();
req.setUserName("zhangsan");
req.setAge(20);
req.setRequestTimestamp(new Date());
String json = JSON.toJSONString(req);
log.info("请求报文:", json);
// 执行addUserService服务
addUserService.execute(new ProcessContext(json), new IFilterCallback()
@Override
public void onPostProcess(ProcessContext context) throws ProcessException
context.setEndServiceTime(System.currentTimeMillis());
long diffTime = context.getEndServiceTime() - context.getStartServiceTime();
log.info("双向责任链执行完毕, 服务耗时" + diffTime);
log.info("响应报文:", context.getJsonResponse());
);
以上是关于基于双向责任链的接口设计的主要内容,如果未能解决你的问题,请参考以下文章