SpringMVC源码学习(二) - DispatcherServlet和相关组件

时间:2022-07-26
本文章向大家介绍SpringMVC源码学习(二) - DispatcherServlet和相关组件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在上期分析中,大概了解了DispatcherServlet的几个组件,这期我们就主要看看后边的几个组件。主要是错误处理转化器、静态资源解析器、视图解析器和flash处理器等。

我们知道如果我们的程序出现了错误,最后报错的是tomcat的线程,在他的前面就是我们servlet了,那么在Servlet这里如何处理这些异常?如果不处理必然导致tomcat线程的崩溃。我个人觉得这里的异常处理器应该就是代码异常的最后处理了。是这样吗?

看到springMvc首先获取所有的HandlerExceptionResolver处理器解析器。然后进行排序什么的一系列处理,最终成为一个列表。

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
    //判断是否能被识别
    if (!this.shouldApplyTo(request, handler)) {
        return null;
    } else {
        //对response进行处理
        this.prepareResponse(ex, response);
        //对异常进行处理
        ModelAndView result = this.doResolveException(request, response, handler, ex);
        if (result != null) {
            if (this.logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
                this.logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result));
                }
                //日志
            this.logException(ex, request);
            }
        return result;
    }
}
protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {
    //handler,可认为是controller等
    if (handler != null) {
    //看会否包含
        if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) {
            return true;
        }
        if (this.mappedHandlerClasses != null) {
            Class[] var3 = this.mappedHandlerClasses;
            int var4 = var3.length;
            for(int var5 = 0; var5 < var4; ++var5) {
                Class<?> handlerClass = var3[var5];
                if (handlerClass.isInstance(handler)) {
                    return true;
                }
            }
        }
    }
    return this.mappedHandlers == null && this.mappedHandlerClasses == null;
}

在这里我们发现默认设置的异常处理的没有浏览器缓存的。

当然这里的异常处理器有很多,看样子是对不同的异常有不同的报错提示。那么它是如何兼容或者找到合适的异常处理器的?觉得这个和SpringApplication中决定是否要有Servlet容器一般应该在调用的时候决定。在后期调用链学习中再看这样的想法是否正确。现在先这样考虑吧。

在initRequestToViewNameTranslator方法中,我们发现这里有前缀和后缀。所以这个RequestToViewNameTranslator应该是传入请求返回一个视图的模块。当然这块应该也是在请求的返回的时候调用。但是通过查看实现类,发现实现类只有一个。

initViewResolvers方法用来初始化视图解析器。

这块也是先从IOC中获取,获取不到到的话采用默认的视图解析器。之前在工作中看到10年的架构师自己写视图解析器的,主要是对返回的的数据比如json或者字符串甚至图片进行处理然后write到outputstream流中。

查看默认实例,发现这块采用的是jsp的视图解析器。

在fashMapManager的初始化也是先从IOC中获取,获取不到则采用默认策略。但是这个FlashMapManager究竟是什么?通过查询网络博客,发现这个是用于防重复提交的。这块后期有机会再专门写一篇吧。我也是在一边学习一边输出,很多说法可能有问题。希望大家多多包含。谢谢大家!