基于双向责任链的接口设计

基于双向责任链的接口设计

基于双向责任链的接口特点如下:

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 filters;

    public LinkedFilerChain(LinkedList 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 filterTemplate;

    /**
     * 最终处理serviceHandler
     */
    private AbstractServiceHandler businessHandler;

    /**
     * 执行一个完整的业务
     */
    public void execute(ProcessContext processContext, IFilterCallback callback) throws ProcessException, InterruptedException {
        log.info("开始处理业务请求: {}", System.nanoTime());

        processContext.setBusinessService(this);

        // 构建责任链
        LinkedList 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、执行责任链

具体执行顺序如下:

  1. JsonConvertFilter
  2. checkRequestTimeFilter
  3. AddUserServiceHandler

3、返回添加用户响应报文AddUserResponse

Spring容器配置xml文件配置addUserService接口如下:

<?xml version="1.0" encoding="UTF-8"?>


    
    

    
        
        
    

    
        
            
        
        
        
            
        
    

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());
            }
        });

    }
}
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章