返回符杰博客列表

Tiny学习笔记(三)

发布于 3月前

上次说到TinyHttpFilter会将传进来的request转为可重复读的request,现在来看看接下来tiny的系统过滤器会做什么处理。

首先会执行requestInitListener这个方法,

private void requestInitListener(ServletRequest servletRequest) {

                   TinyListenerConfigManager configManager = TinyListenerConfigManagerHolder

                                     .getInstance();

                   List<ServletRequestListener> listeners = configManager

                                     .getRequestListeners();//拿到request初始化监听器链(监听器一般实现了order接口,所以在这里拿到的监听器链已经经过排序。从官网的解释也能看出这一点)

                   ServletRequestEvent event = new ServletRequestEvent(

                                     ServletContextHolder.getServletContext(), servletRequest);

                   for (ServletRequestListener listener : listeners) {

                            logger.logMessage(LogLevel.DEBUG,

                                               "ServletRequestListener:[{0}] will be requestInitialized",

                                               listener);

                            listener.requestInitialized(event);//执行监听器方法

                            logger.logMessage(LogLevel.DEBUG,

                                               "ServletRequestListener:[{0}] requestInitialized", listener);

                   }

         }

通过tiny的监听管理器拿到监听器执行对request初始化事件的操作。

接下来是putMDC(request, response) 作用是记录一些日志信息,其中的关键在于putTHreadVariable这个方法

public static void putThreadVariable(String key, String value) {

        putThreadVariable(key, value, threadVariableMap);

        if (isRpcVariableKey(key)) {

            putThreadVariable(key, value, threadRpcVariableMap);

        }

    }

    private static void putThreadVariable(String key, String value,

                                          ThreadLocal<Map<String, String>> map) {

        Map<String, String> valueMap = map.get();

        if (valueMap == null) {

            valueMap = new HashMap<String, String>();

            map.set(valueMap);

        }

        if (valueMap.size() <= 10000) {

            valueMap.put(key, value);

        }

    }

可以发现多个线程对应的多个请求之间的日志记录并不影响,这是因为每个线程都是从threadlocal中取的对应map,线程之间是不可见的。

随后进行一些web上下文的初始化,一些信息的填充。

         判断是否以”/”结尾,加载默认的页面(比如index.page)

if (servletPath.endsWith("/")) {

                                     for (String defaultFile : defaultFiles) {

                                               String tmpPath = servletPath + defaultFile;

                                               FileObject fileObject = fullContextFileRepository

                                                                 .getFileObject(tmpPath);

                                               if (fileObject != null && fileObject.isExist()) {

                                                        servletPath = tmpPath;

                                                        request.setAttribute(DEFAULT_PAGE_KEY, servletPath);

                                                        break;

                                               }

                                     }

                            }

         判断是否有原始过滤器如果有先走过滤器链,否则直接执行TinyProcess过滤逻辑。

                            if (wrapper != null) {

                                     wrapper.filterWrapper(context, handler);

                            } else {

                                     handler.tinyFilterProcessor(request, response);

                            }

         来看看filterWrapper方法

         public void filterWrapper(WebContext context, FilterHandler handler)

            throws IOException, ServletException {

        HttpServletRequest request = context.getRequest();

        HttpServletResponse response = context.getResponse();

        String servletPath = handler.getServletPath();

                   //获得过滤器链

        List<Filter> matchFilters = getMatchFilters(servletPath, filterMap);

        logger.logMessage(LogLevel.DEBUG,

                "the pre wrapper httpFilters for the request path:[{0}] is [{1}]",

                servletPath, matchFilters);

        TinyFilterChain filterChain = new TinyFilterChain(matchFilters, handler);

                   //执行过滤器方法

        filterChain.doFilter(request, response);

     }

         看看doFilter的实现

         public void doFilter(ServletRequest request, ServletResponse response)

            throws IOException, ServletException {

        if (currentPosition < size) {//标志过滤器链的执行位置

            Filter nextFilter = filters.get(currentPosition);

            logger.logMessage(LogLevel.DEBUG, "firing Filter:'{}'", nextFilter

                    .getClass().getSimpleName());

            currentPosition++;

            nextFilter.doFilter(request, response, this);

        } else {

            initWebContext(request, response);//重新初始化webcontext中保存的request和response对象

            tinyFilterHandler.tinyFilterProcessor((HttpServletRequest) request, (HttpServletResponse) response);// 执行TinyProcess过滤逻辑

        }

}

从官网的解释可以以看出Tiny过滤器分为两类:封装过滤器(tiny-wrapper-filter)和一般过滤器(tiny-filter)。但是无论有没有封装过滤器,从代码都可以看出最终都会执行到tinyFilterProcessor。


 
相关信息
     标签
       附件
      文件 标题 创建者

      评分 0次评分

      日程