拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Spring核心原理分析之MVC九大组件(1)

Spring核心原理分析之MVC九大组件(1)

白鹭 - 2022-03-04 1994 0 0

1 什么是Spring MVC

Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,Spring MVC 角色划分清晰,分工明细,由于 Spring MVC 本身就是 Spring 框架的一部分,可以说和 Spring 框架是无缝集成,性能方面具有先天的优越性,是当今业界最主流的 Web 开发框架,最热门的开发技能,
首先从一个由Spring提供的DispatcherServlet开始,重写了Serlvet的init()方法、service()方法和destroy()方法,SpringMVC九大组件在DispatcherServlet的init()方法中初始化,在service()方法中执行,下面,我们先来看Spring MVC九大组件的初始化,

2 SpringMVC九大组件名称解释

Spring MVC九大组件在DispatcherServlet的init()方法中初始化,下面我详细介绍一下Spring MVC九大组件的名称和作用,

序号 组件名 解释
1 MultipartResolver 用于处理多档案上传请求,
2 LocaleResolver 用于从请求中决议出 Locale,是i18n的基础,
3 ThemeResolver 用来决议样式、图片及它们所形成的显示效果的集合,
4 HandlerMapping 保存Url和逻辑处理的映射关系,
5 HandlerAdapter 动态自变量配接器,让固定的Servlet处理方法呼叫Handler来进行处理
6 HandlerExceptionResolver 用来处理Handler产生的例外情况的组件,
7 RequestToViewNameTranslator 从请求中获取ViewName
8 ViewResolvers 主要作用是将String型别的视图名和Locale决议为View型别的视图
9 FlashMapManager 用于重定向时的自变量传递,

具体详细介绍如下:

2.1 MultipartResolver

MultipartResolver是一个大家很熟悉的组件,用于处理上传请求,通过将普通的请求包装成MultipartHttpServletRequest来实作,MultipartHttpServletRequest可以通过getFile()方法直接获得档案,如果上传多个档案,还可以呼叫getFileMap()方法得到 Map< FileName, File> 这样的结构,MultipartResolver的作用就是封装普通的请求,使其拥有档案上传的功能,

2.2 LocaleResolver

ViewResolver组件的resolveViewName()方法需要两个自变量,一个是视图名,另一个就是Locale,自变量Locale是从哪来的呢?这就是LocaleResolver组件要做的事,LocaleResolver用于从请求中决议出 Locale,比如在中国Locale当然就是zh-CN,用来表示一个区域,这个组件也是i18n的基础,

2.3 ThemeResolver

从名字便可看出,ThemeResolver组件是用来决议主题的,主题就是样式、图片及它们所形成的显示效果的集合,Spring MVC中一套主题对应一个properties档案,里面存放着与当前主题相关的所有资源,如图片、CSS样式等,创建主题非常简单,只需准备好资源,然后新建一个“主题名.properties”并将资源设定进去,放在classpath下,之后便可以在页面中使用了,Spring MVC中与主题有关的类有ThemeResolver、ThemeSource和Theme,ThemeResolver负责从请求中决议出主题名,ThemeSource则根据主题名找到具体的主题,其抽象也就是Theme,可以通过Theme来获取主题和具体的资源,

2.4 HandlerMapping

HandlerMapping是用来查找Handler的,也就是处理器,具体的表现形式可以是类,也可以是方法,比如,标注了@RequestMapping的每个方法都可以看成一个Handler,Handler负责实际的请求处理,在请求到达后,HandlerMapping的作用便是找到请求相应的处理器Handler和Interceptor,

2.5 HandlerAdapter

从名字上看,HandlerAdapter是一个配接器,因为Spring MVC中Handler可以是任意形式的,只要能够处理请求便可,但是把请求交给Servlet的时候,由于Servlet的方法结构都是doService(HttpServletRequest req, HttpServletResponse resp)形式的,要让固定的Servlet处理方法呼叫Handler来进行处理,这一步作业便是HandlerAdapter要做的事,

2.6 HandlerExceptionResolver

从组件的名字上看,HandlerExceptionResolver是用来处理Handler产生的例外情况的组件,具体来说,此组件的作用是根据例外设定ModelAndView,之后交给渲染方法进行渲染,渲染方法会将ModelAndView渲染成页面,不过要注意,HandlerExceptionResolver只用于决议对请求做处理阶段产生的例外,渲染阶段的例外不归它管,这也是Spring MVC 组件设计的一大原则—分工明确、互不干涉,

2.7 RequestToViewNameTranslator

RequestToViewNameTranslator组件的作用是从请求中获取ViewName,因为ViewResolver根据ViewName查找View,但有的Handler处理完成之后,没有设定View,也没有设定ViewName,便要通过这个组件来从请求中查找ViewName,

2.8 ViewResolver

ViewResolver即视图决议器,相信大家对这个组件应该很熟悉了,通常在Spring MVC的组态档中,都会配上一个实作类来进行视图决议,这个组件的主要作用是将String型别的视图名和Locale决议为View型别的视图,只有一个resolveViewName()方法,从方法的定义可以看出,Controller层回传的String型别的视图名viewName最侄训在这里被决议成为View,View是用来渲染页面的,也就是说,它会将程序回传的自变量和资料填入模板中,生成HTML档案,ViewResolver在这个程序中主要做两件大事:ViewResolver会找到渲染所用的模板(第一件大事)和所用的技术(第二件大事,其实也就是找到视图的型别,如JSP)并填入自变量,默认情况下,Spring MVC会为我们自动配置一个InternalResourceViewResolver,是针对JSP型别视图的,

2.9 FlashMapManager

说到FlashMapManager组件,得先说一下FlashMap,
FlashMap用于重定向时的自变量传递,比如在处理用户订单时,为了避免重复提交,可以处理完post请求后重定向到一个get请求,这个get请求可以用来显示订单详情之类的信息,这样做虽然可以规避用户重新提交订单的问题,但是在这个页面上要显示订单的信息,这些资料从哪里获取呢?因为重定向是没有传递自变量这一功能的,如果不想把自变量写进URL(其实也不推荐这幺做,除了URL有长度限制,把自变量都直接暴露也不安全),那么就可以通过FlashMap来传递,只需要在重定向之前将要传递的资料写入请求(可以通过ServletRequestAttributes.getRequest()方法获得)的属性OUTPUT_FLASH_MAP_ATTRIBUTE中,这样在重定向之后的Handler中Spring就会自动将其设定到Model中,在显示订单信息的页面上就可以直接从Model中获得资料,
FlashMapManager就是用来管理FlashMap的,

3 Spring MVC关键组件的执行流程

Spring MVC九大组件的执行在DispatcherServlet的service()方法中完成,在这里,我重点介绍几个关键组件HandlerMapping、HandlerAdapter、ViewResolver在service()方法中的执行流程,具体呼叫分为以下几个步骤:

1、HandlerMapping回到呼叫HandlerAdapter

2、HandlerAdapter会回传ModelAndView

3、ModelAndView根据用户传入自变量得到ViewResolvers

4、ViewResolvers会将用户传入的自变量封装为View,交给引擎进行渲染,

下面给大家分享一张Spring MVC关键组件的执行流程图,以帮助大家更好地理解:

file

4 Spring MVC优化建议

前面我们已经对Spring MVC的作业原理和原始码进行了分析,在这个程序中有几个优化点,

1. Controller如果能保持单例模式,尽量使用单例模式

这样可以减小创建物件和回收物件的开销,也就是说,如果Controller的类变量和实体变量可以以方法形参宣告就尽量以方法形参宣告,不要以类变量和实体变量宣告,这样可以避免执行绪安全问题,

2. 处理请求的方法中的形参务必加上@RequestParam注解

这样可以避免Spring MVC使用asm框架读取.class档案获取方法自变量名,即便Spring MVC对读取出的方法自变量名进行了快取,如果能不读取.class档案当然更好,

3. 快取URL

在阅读原始码的程序中,我们发现Spring MVC并没有对处理URL的方法进行快取,也就是说,每次都要根据请求URL去匹配Controller中的方法的URL,如果把URL和方法的关系快取起来,会不会带来性能上的提升呢?不幸的是,负责决议URL和方法对应关系的ServletHandlerMethodResolver是一个私有的内部类,不能直接通过继承该类增强代码,必须在代码后重新编译,当然,如果将URL快取起来,必须考虑快取的执行绪安全问题,

原创不易,坚持很酷,都看到这里了,小伙伴记得点赞、收藏、在看,一键三连加关注!如果你觉得内容太干,可以分享转发给朋友滋润滋润!

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *