专栏首页一杯82年的JAVA从0.5到1写个rpc框架 - 4:request filter

从0.5到1写个rpc框架 - 4:request filter

为了后续扩展方便,搞个filter支持,就抄一个servlet的filter吧。

servlet filter 分析

在写mvc项目时,经常会用到filter,可以给一个请求做前置或者后置处理。如下:

@WebFilter(filterName = "requestFilter", urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
        System.out.println("我进来了");
        chain.doFilter(request, response);
        System.out.println("我要走了");
    }

    @Override
    public void destroy() {
        System.out.println("filter destroy");
    }
}

这是一种责任链模式的实现,debug看下调用栈可以了解框架是怎么实现的。

  • 每次请求生成一个FilterChain对象,并使其持有所有filter的数组,初始化成员变量pos=0(表示应该执行第几个filter)
  • 从FilterChain.doFilter开始调用整个链路,从第一个filter开始,调用时会把chain本身传给filter,pos自增
  • 某个filter如果不拦截这个请求,则调用FilterChain.doFilter,由于pos已经自增,则会调用下一个filter
  • filter全部调用后(pos=filters.length),开始真正执行请求
  • 请求返回后会依次再经过之前经过的所有filter(倒序)

rpc filter 实现

定义filter接口,使用者如果要添加过滤逻辑需要集成这个接口。

public interface RpcFilter {
    void doFilter(RpcRequest request, RpcResponse response, RpcFilterChain filterChain);
}

filter持有者

public class RpcFilterChain implements RpcCode {
    private RpcFilter[] filters = new RpcFilter[0];
    private int pos;
    private RpcServiceInfo serviceInfo;
    private RpcServiceExecutor serviceExecutor;//最终要执行请求的处理器

    public RpcFilterChain(List<RpcFilter> filterList, RpcServiceInfo serviceInfo, RpcServiceExecutor serviceExecutor) {
        if (filterList != null && !filterList.isEmpty()) {
            this.filters = new RpcFilter[filterList.size()];
            this.filters = filterList.toArray(this.filters);
        }
        this.serviceInfo = serviceInfo;
        this.serviceExecutor = serviceExecutor;
    }

    public void doFilter(RpcRequest request, RpcResponse response) {
        if (pos < filters.length) {
            RpcFilter filter = filters[pos++];
            filter.doFilter(request, response, this);
            return;
        }
        if (serviceExecutor == null) {
            response.error(SERVICE_NOT_FOUND, "service not exist: " + serviceInfo);
            return;
        }
        serviceExecutor.execute(request, response);
    }

}

rpc server 接收到请求后先初始化一个责任链,然后触发。

public RpcResponse execute(RpcRequest rpcRequest) {
        RpcServiceInfo rpcServiceInfo = new RpcServiceInfo(rpcRequest.getAppName(), rpcRequest.getServiceName());
        RpcFilterChain chain = new RpcFilterChain(filters, rpcServiceInfo, serviceExecutorMap.get(rpcServiceInfo));
        RpcResponse rpcResponse = new RpcResponse();
        try {
            chain.doFilter(rpcRequest, rpcResponse);
        } catch (Exception e) {
            rpcResponse.error(e);
        }
        return rpcResponse;
    }

本文分享自微信公众号 - 一杯82年的JAVA(acupjava),作者:acupt

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux实践 - 创建用户

    PS: 记不住ip,所以在个人电脑的hosts文件中设置了个别名,因为用的腾讯云服务器,就叫qqcloud。

    acupt
  • 从0.5到1写个rpc框架 - 5:服务监控和管理(actuator)

    springboot项目中只要引入spring-boot-starter-actuator就可以得到一些管理服务的接口,比如停止服务,获取服务信息等。他用的并不...

    acupt
  • JAVA泛型与类型擦除

    为什么要用T而不是其它字母?事实上是可以任意字符串(如Result< something >),但是为了显得专业,一般约定几个大写字母在不同场景使用。

    acupt
  • java后台开发- NOTE

    2015-1-6: IDEA servlet-api.jar    idea从14升级到15后,发现 import javax.servlet.AsyncCon...

    梦里茶
  • Filter过滤器

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet。 1.过滤器的概念 Java中的Filter 并不是一个...

    汤高
  • Java ---Filter过滤器

         Filter可以视作是servlet的加强版,主要用作对用户的请求进行预处理,或者对返回给客户端的结果进行再次加工,是一个典型的链式处理模式。本篇简单...

    Single
  • 一行代码使网站变灰

    根据国务院公告,定于2020年4月4日10时,为抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞举行哀悼活动。

    前端黑板报
  • python3和python2中的filter区别

    python3中的filter与python2中的是不一样的 其中,在python2中

    周小董
  • 碎片化 | 第四阶段-28-Struts2框架概述以及原理图解-视频

    如清晰度低,可转PC网页观看高清版本: http://v.qq.com/x/page/o05656uacql.html Struts2 概述 Strut...

    码神联盟
  • 细说shiro之自定义filter

    我们知道,shiro框架在Java Web应用中使用时,本质上是通过filter方式集成的。 也就是说,它是遵循过滤器链规则的:filter的执行顺序与在we...

    2Simple

扫码关注云+社区

领取腾讯云代金券