Spring MVC组件源码分析

组件概览

HandlerMapping

根据 request 找到对应的处理器 Handler 和 Interceptors。内部只有一个方法

HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

HandlerAdapter

Handler 适配器,内部方法如下:

boolean supports(Object handler);//判断是否可以使用某个 Handler
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; //具体使用
long getLastModified(HttpServletRequest request, Object handler);//获取资源上一次修改的时间

HandlerExceptionResolver

根据异常设置 ModelAndView ,再交给 render 方法进行渲染。

ModelAndView resolveException(
            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex)

ViewResolver

用来将 String 类型的视图名和 Locale 解析为 View 类型的视图。

View resolveViewName(String viewName, Locale locale) throws Exception;

它的一个实现类 BeanNameViewResolver,它重写 resolveViewName 方法如下:

public View resolveViewName(String viewName, Locale locale) throws BeansException {
        ApplicationContext context = getApplicationContext();
        //如果应用上下文没有找到视图,返回 null
        if (!context.containsBean(viewName)) {
            if (logger.isDebugEnabled()) {
                logger.debug("No matching bean found for view name '" + viewName + "'");
            }
            // Allow for ViewResolver chaining...
            return null;
        }
        //如果找到的视图类型不匹配,也返回 null
        if (!context.isTypeMatch(viewName, View.class)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Found matching bean for view name '" + viewName +
                        "' - to be ignored since it does not implement View");
            }
            // Since we're looking into the general ApplicationContext here,
            // let's accept this as a non-match and allow for chaining as well...
            return null;
        }
        //根据视图名称从 Spring 容器中查找 Bean,返回找到的 bean
        return context.getBean(viewName, View.class);
    }

RequestToViewNameTranslator

获取 request 中的视图名。接口里面也是只有一个方法:

String getViewName(HttpServletRequest request) throws Exception; //根据 request 查找视图名

LocaleResolver

用于从 request 解析出 Locale。

public interface LocaleResolver {
    //从 request 解析出 Locale
    Locale resolveLocale(HttpServletRequest request);
    //根据 request 设置  locale
    void setLocale(HttpServletRequest request, HttpServletResponse response, @Nullable Locale locale);
}

ThemeResolver

解析主题

public interface ThemeResolver {
    //通过给定的 request 查找主题名
    String resolveThemeName(HttpServletRequest request);
    //根据给定的 request 设置主题名
    void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName);
}

在 RequestContext.java 文件中可以获取主题:

public String getThemeMessage(String code, String defaultMessage) {
        //获取主题的信息
        return getTheme().getMessageSource().getMessage(code, null, defaultMessage, this.locale);
    }

public Theme getTheme() {
        //判断主题是否为空
        if (this.theme == null) {
            // 通过 RequestContextUtils 获取 request 中的主题名
            this.theme = RequestContextUtils.getTheme(this.request);
            if (this.theme == null) {   //如果还是为空的话
                //那就是没有有效的主题解析器和主题
                this.theme = getFallbackTheme();
            }
        }
        return this.theme;
    }

RequestContextUtils.getTheme() 方法:

public static Theme getTheme(HttpServletRequest request) {
        ThemeResolver themeResolver = getThemeResolver(request);
        ThemeSource themeSource = getThemeSource(request);
        if (themeResolver != null && themeSource != null) {
            String themeName = themeResolver.resolveThemeName(request);
            return themeSource.getTheme(themeName);
        }
        else {
            return null;
        }
    }

MultipartResolver

用于处理上传请求,处理方法:将普通的 request 包装成 MultipartHttpServletRequest

public interface MultipartResolver {
    //根据 request 判断是否是上传请求
    boolean isMultipart(HttpServletRequest request);
    //将 request 包装成 MultipartHttpServletRequest
    MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
    //清理上传过程中产生的临时资源
    void cleanupMultipart(MultipartHttpServletRequest request);
}

FlashMapManager

FlashMap 主要在 redirect 中传递参数,FlashMapManager 用来管理 FlashMap 的。

public interface FlashMapManager {
    //恢复参数,并将恢复过的和超时的参数从保存介质中删除
    @Nullable
    FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);
    //将参数保存起来
    void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}

小结

介绍 Spring MVC 中九大组件的接口、作用、内部方法实现及作用进行了简单的介绍,详细的还需大家自己去看源码。

总结

Spring MVC 原理总结

本质是一个 Servlet,这个 Servlet 继承自 HttpServlet。Spring MVC 中提供了三个层次的 Servlet:HttpServletBean、FrameworkServlet 和 DispatcherServlet。他们相互继承, HttpServletBean 直接继承自 Java 的 HttpServlet。HttpServletBean 用于将 Servlet 中的 Servlet 中配置的参数设置到相应的属性中,FrameworkServlet 初始化了 Spring MVC 中所使用的 WebApplicationContext,具体处理请求的 9 大组件是在 DispatcherServlet 中初始化的,整个继承图如下:

Spring MVC组件源码分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前言 第一篇 网站基础知识 第1章 网站架构及其演变过程2 1.1 软件的三大类型2 1.2 基础的结构并不简单3 1.3 架构演变的起点5 1.4 海量数据的解决方案5 1.4.1 缓存和页面静态化5 1.4.2 数据库优化6 1.4.3 分离活跃数据8 1.4.4 批量读取和延迟修改8 1.4.5 读写分离9 1.4.6 分布式数据库10 1.4.7 NoSQL和Hadoop10 1.5 高并发的解决方案11 1.5.1 应用和静态资源分离11 1.5.2 页面缓存12 1.5.3 集群与分布式12 1.5.4 反向代理13 1.5.5 CDN14 1.6 底层的优化15 1.7 小结15 第2章 常见协议和标准17 2.1 DNS协议17 2.2 TCP/IP协议与Socket18 2.3 HTTP协议20 2.4 Servlet与Java Web开发22 第3章 DNS的设置23 3.1 DNS解析23 3.2 Windows 7设置DNS服务器24 3.3 Windows设置本机域名和IP的对应关系25 第4章 Java中Socket的用法26 4.1 普通Socket的用法26 4.2 NioSocket的用法28 第5章 自己动手实现HTTP协议33 第6章 详解Servlet37 6.1 Servlet接口37 6.2 GenericServlet40 6.3 HttpServlet41 第7章 Tomcat分析44 7.1 Tomcat的顶层结构及启动过程44 7.1.1 Tomcat的顶层结构44 7.1.2 Bootstrap的启动过程45 7.1.3 Catalina的启动过程47 7.1.4 Server的启动过程48 7.1.5 Service的启动过程50 7.2 Tomcat的生命周期管理52 7.2.1 Lifecycle接口52 7.2.2 LifecycleBase53 7.3 Container分析59 7.3.1 ContainerBase的结构59 7.3.2 Container的4个子容器60 7.3.3 4种容器的配置方法60 7.3.4 Container的启动62 7.4 Pipeline-Value管道69 7.4.1 Pipeline-Value处理模式69 7.4.2 Pipeline-Value的实现方法70 7.5 Connector分析73 7.5.1 Connector的结构73 7.5.2 Connector自身类74 7.5.3 ProtocolHandler77 7.5.4 处理TCP/IP协议的Endpoint77 7.5.5 处理HTTP协议的Processor80 7.5.6 适配器Adapter81 第二篇 俯视Spring MVC 第8章 Spring MVC之初体验84 8.1 环境搭建84 8.2 Spring MVC最简单的配置84 8.2.1 在web.xml中配置Servlet85 8.2.2 创建Spring MVC的xml配置文件85 8.2.3  创建Controller和view86 8.3 关联spring源代码87 8.4 小结89 第9章 创建Spring MVC之器90 9.1 整体结构介绍90 9.2 HttpServletBean93 9.3 FrameworkServlet95 9.4 DispatcherServlet100 9.5 小结107 第10章 Spring MVC之用108 10.1 HttpServletBean108 10.2 FrameworkServlet108 10.3 DispatcherServlet114 10.4 doDispatch结构118 10.5 小结123 第三篇 Spring MVC组件分析 第11章 组件概览126 11.1 HandlerMapping126 11.2 HandlerAdapter128 11.3 HandlerExceptionResolver130 11.4 ViewResolver131 11.5 RequestToViewNameTranslator133 11.6 LocaleResolver133 11.7 ThemeResolver135 11.8 MultipartResolver137 11.9 FlashMapManager138 11.10 小结139 第12章 HandlerMapping140 12.1 AbstractHandlerMapping140 12.1.1 创建AbstractHandlerMapping之器141 12.1.2 AbstractHandlerMapping之用142 12.2 AbstractUr

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值