1什么是SpringMVCSpringMVC是Spring提供的基于MVC设计模式的轻量级Web开发框架,本质上等同于Servlet。SpringMVC角色分工明确,分工细化。由于SpringMVC本身就是Spring框架的一部分,可以说是与Spring框架无缝集成。在性能方面,它具有先天优势。它是当今业界最主流的Web开发框架和最流行的开发技巧。首先从Spring提供的一个DispatcherServlet入手,重写Serlvet的init()方法、service()方法和destroy()方法。SpringMVC的九个组件在DispatcherServlet的init()方法中初始化,在service()方法中初始化。实施。接下来我们先来看一下SpringMVC的九个组件的初始化。2SpringMVC九大组件名称解释SpringMVC的九大组件都是在DispatcherServlet的init()方法中初始化的。下面详细介绍一下SpringMVC的九大组件的名称和作用。具体如下:2.1MultipartResolverMultipartResolver是大家比较熟悉的处理上传请求的组件,它是通过将普通请求封装成MultipartHttpServletRequest来实现的。MultipartHttpServletRequest可以直接通过getFile()方法获取文件。如果上传多个文件,也可以调用getFileMap()方法获取类似Map的结构。MultipartResolver的作用是对普通请求进行封装,使其具有文件上传的功能。2.2LocaleResolverResolver组件的resolveViewName()方法需要两个参数,一个是视图名称,一个是Locale。Locale参数从何而来?这就是LocaleResolver组件的作用。LocaleResolver用于从请求中解析Locale。比如在中国,Locale当然是zh-CN,用来表示一个地区。该组件也是i18n的基础。2.3ThemeResolver顾名思义,ThemeResolver组件就是用来解析主题的。主题是样式、图像及其形成的显示效果的集合。SpringMVC中的一套主题对应一个属性文件,里面存放了与当前主题相关的所有资源,比如图片、CSS样式等。创建一个主题很简单,只要准备好资源,然后创建一个新的“主题”name.properties”并在里面设置资源,放到classpath下,就可以在页面中使用了。SpringMVC中与主题相关的类有ThemeResolver、ThemeSource和Theme。ThemeResolver负责从请求中解析出主题名称,ThemeSource根据主题名称找到具体的主题。它的抽象是Theme,可以通过Theme获取主题和具体的资源。2.4HandlerMappingHandlerMapping用于查找Handler,即处理器。具体的表现形式可以是一个类,也可以是一个方法。比如每一个用@RequestMapping标记的方法都可以看成是一个Handler。Handler负责实际的请求处理。请求到达后,HandlerMapping的作用就是找到请求对应的处理器Handler和Interceptor。2.5HandlerAdapter从名字上看,HandlerAdapter是一个适配器。因为SpringMVC中的Handler可以是任何形式,只要能处理请求即可。但是当请求交给Servlet时,由于Servlet的方法结构是doService(HttpServletRequestreq,HttpServletResponseresp)的形式,所以需要让固定的Servlet处理方法调用Handler进行处理。这一步是HandlerAdapter必须做的。2.6HandlerExceptionResolver从组件的名字看,HandlerExceptionResolver是一个用来处理Handler产生的异常的组件。具体来说,这个组件的作用就是根据异常设置ModelAndView,然后交给渲染方法进行渲染。呈现方法会将ModelAndView呈现到页面中。但是需要注意的是,HandlerExceptionResolver只是用来解决请求处理阶段产生的异常,渲染阶段的异常不受其控制。这也是SpringMVC组件设计的一大原则——分工明确,互不干扰。2.7RequestToViewNameTranslatorRequestToViewNameTranslator组件的作用是从请求中获取ViewName。因为ViewResolver是根据ViewName找到View的,但是经过一些Handlers处理后,View和ViewName都没有设置,所以这个组件就是用来从请求中找到ViewName的。2.8ViewResolverViewResolver就是视图解析器,相信大家对这个组件应该不陌生。通常在SpringMVC的配置文件中,会添加一个实现类,用于视图解析。该组件的主要功能是将String类型的视图名称和Locale解析成View类型的视图,只有一个resolveViewName()方法。从方法的定义可以看出,Controller层返回的String类型的视图名viewName,最终会在这里解析成View。View是用来渲染页面的,也就是说,它将程序返回的参数和数据填充到模板中,生成一个HTML文件。ViewResolver在这个过程中主要做了两件大事:ViewResolver会寻找用于渲染的模板(第一件大事)和使用的技术(第二件大事,其实就是寻找view的类型,比如JSP)并填写参数。默认情况下,SpringMVC会自动为我们配置一个InternalResourceViewResolver,它是针对JSP类型视图的。2.9FlashMapManager说到FlashMapManager组件,首先要说的就是FlashMap。FlashMap用于重定向时的参数传递。比如在处理用户订单时,为了避免重复提交,可以在处理完post请求后重定向到一个get请求。此获取请求可用于显示订单详细信息等信息。这样虽然可以避免用户重新提交订单的问题,但是要在这个页面显示订单信息,数据从哪里获取呢?因为重定向没有传递参数的功能,如果不想把参数写到URL中(其实不建议这样做,只是URL有长度限制,不安全直接暴露参数),就可以通过FlashMap传递了。只需要在重定向前将要传递的数据写入请求的属性OUTPUT_FLASH_MAP_ATTRIBUTE(可通过ServletRequestAttributes.getRequest()方法获取),这样Spring会在重定向后自动设置到Handler中的Model中,并显示数据可以直接从订单信息页面的模型中获取。FlashMapManager用于管理FlashMap。3SpringMVC关键组件的执行过程SpringMVC的九大组件的执行都是在DispatcherServlet的service()方法中完成的。在这里,我将重点介绍几个关键组件HandlerMapping、HandlerAdapter、ViewResolver在service()方法中的执行过程。具体调用分为以下几个步骤:1.HandlerMapping返回调用HandlerAdapter2,HandlerAdapter会返回ModelAndView3。ModelAndView根据用户传入的参数得到ViewResolvers4,ViewResolvers会将用户传入的参数封装成一个View,交给引擎进行渲染。给大家分享一个SpringMVC关键组件的执行流程图,帮助大家更好的理解:注:上图中有两个类大家最熟悉:ModelAndView和View类不属于九大类SpringMVC列表的组件。4SpringMVC优化建议我们分析了SpringMVC的工作原理和源码,在这个过程中有几个优化点。1.如果Controller可以保持单例模式,尽量使用单例模式,减少创建和回收对象的开销。也就是说,如果Controller的类变量和实例变量可以用方法参数声明,尽量用方法参数声明,而不是类变量和实例变量,这样可以避免线程安全问题。2、请求处理方法中的形参必须使用@RequestParam注解,防止SpringMVC使用asm框架读取.class文件获取方法参数名。即使SpringMVC缓存了读取的方法参数名,如果不能读取.class文件就更好了。3、缓存URL在阅读源码的过程中,我们发现SpringMVC并没有缓存URL处理的方法,即每次需要根据请求URL去匹配Controller中方法的URL,如果URL和method会带来性能提升吗?不幸的是,负责解析URL和方法之间关系的ServletHandlerMethodResolver是一个私有的内部类,继承这个类不能直接增强代码。它必须在代码编译后重新创建。当然,如果缓存了URL,就要考虑缓存的线程安全问题。