先来看一下什么是 MVC 模式

MVC 是一种设计模式.

MVC 的原理图如下:

SpringMVC 简单介绍

SpringMVC 框架是以请求为驱动,围绕 Servlet 设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是 DispatcherServlet,它是一个 Servlet,顶层是实现的Servlet接口。

SpringMVC 使用

需要在 web.xml 中配置 DispatcherServlet 。并且需要配置 Spring 监听器ContextLoaderListener

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 如果不设置init-param标签,则必须在/WEB-INF/下创建xxx-servlet.xml文件,其中xxx是servlet-name中配置的名称。 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/springmvc-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>
复制代码

SpringMVC 工作原理(重要)

简单来说:

客户端发送请求-> 前端控制器 DispatcherServlet 接受客户端请求 -> 找到处理器映射 HandlerMapping 解析请求对应的 Handler-> HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑 -> 处理器返回一个模型视图 ModelAndView -> 视图解析器进行解析 -> 返回一个视图对象->前端控制器 DispatcherServlet 渲染数据(Moder)->将得到视图对象返回给用户

如下图所示:

上图的一个笔误的小问题:Spring MVC 的入口函数也就是前端控制器 DispatcherServlet 的作用是接收请求,响应结果。

流程说明(重要):

(1)客户端(浏览器)发送请求,直接请求到 DispatcherServlet。

(2)DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。

(3)解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。

(4)HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。

(5)处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。

(6)ViewResolver 会根据逻辑 View 查找实际的 View。

(7)DispaterServlet 把返回的 Model 传给 View(视图渲染)。

(8)把 View 返回给请求者(浏览器)

SpringMVC 重要组件说明

1、前端控制器DispatcherServlet(不需要工程师开发),由框架提供(重要)

作用:Spring MVC 的入口函数。接收请求,响应结果,相当于转发器,中央处理器。有了 DispatcherServlet 减少了其它组件之间的耦合度。用户请求到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。

2、处理器映射器HandlerMapping(不需要工程师开发),由框架提供

作用:根据请求的url查找Handler。HandlerMapping负责根据用户请求找到Handler即处理器(Controller),SpringMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

3、处理器适配器HandlerAdapter

作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler 通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

4、处理器Handler(需要工程师开发)

注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。 由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。

5、视图解析器View resolver(不需要工程师开发),由框架提供

作用:进行视图解析,根据逻辑视图名解析成真正的视图(view) View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。 springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面。

6、视图View(需要工程师开发)

View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

注意:处理器Handler(也就是我们平常说的Controller控制器)以及视图层view都是需要我们自己手动开发的。其他的一些组件比如:前端控制器DispatcherServlet、处理器映射器HandlerMapping、处理器适配器HandlerAdapter等等都是框架提供给我们的,不需要自己手动开发。

DispatcherServlet详细解析

首先看下源码:

package org.springframework.web.servlet;@SuppressWarnings("serial")
public class DispatcherServlet extends FrameworkServlet {public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION";public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);private static final Properties defaultStrategies;static {try {ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);}catch (IOException ex) {throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());}}/** Detect all HandlerMappings or just expect "handlerMapping" bean? */private boolean detectAllHandlerMappings = true;/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */private boolean detectAllHandlerAdapters = true;/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */private boolean detectAllHandlerExceptionResolvers = true;/** Detect all ViewResolvers or just expect "viewResolver" bean? */private boolean detectAllViewResolvers = true;/** Throw a NoHandlerFoundException if no Handler was found to process this request? **/private boolean throwExceptionIfNoHandlerFound = false;/** Perform cleanup of request attributes after include request? */private boolean cleanupAfterInclude = true;/** MultipartResolver used by this servlet */private MultipartResolver multipartResolver;/** LocaleResolver used by this servlet */private LocaleResolver localeResolver;/** ThemeResolver used by this servlet */private ThemeResolver themeResolver;/** List of HandlerMappings used by this servlet */private List<HandlerMapping> handlerMappings;/** List of HandlerAdapters used by this servlet */private List<HandlerAdapter> handlerAdapters;/** List of HandlerExceptionResolvers used by this servlet */private List<HandlerExceptionResolver> handlerExceptionResolvers;/** RequestToViewNameTranslator used by this servlet */private RequestToViewNameTranslator viewNameTranslator;private FlashMapManager flashMapManager;/** List of ViewResolvers used by this servlet */private List<ViewResolver> viewResolvers;public DispatcherServlet() {super();}public DispatcherServlet(WebApplicationContext webApplicationContext) {super(webApplicationContext);}@Overrideprotected void onRefresh(ApplicationContext context) {initStrategies(context);}protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);initHandlerMappings(context);initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}
}
复制代码

DispatcherServlet类中的属性beans:

HandlerMapping:用于handlers映射请求和一系列的对于拦截器的前处理和后处理,大部分用@Controller注解。

  • HandlerAdapter:帮助DispatcherServlet处理映射请求处理程序的适配器,而不用考虑实际调用的是 哪个处理程序。- - -
  • ViewResolver:根据实际配置解析实际的View类型。
  • ThemeResolver:解决Web应用程序可以使用的主题,例如提供个性化布局。
  • MultipartResolver:解析多部分请求,以支持从HTML表单上传文件。-
  • FlashMapManager:存储并检索可用于将一个请求属性传递到另一个请求的input和output的FlashMap,通常用于重定向。
  • 在Web MVC框架中,每个DispatcherServlet都拥自己WebApplicationContext,它继承了ApplicationContext。WebApplicationContext包含了其上下文和Servlet实例之间共享的所有的基础框架beans。

HandlerMapping

HandlerMapping接口处理请求的映射HandlerMapping接口的实现类:

  • SimpleUrlHandlerMapping类通过配置文件把URL映射到Controller类。
  • DefaultAnnotationHandlerMapping类通过注解把URL映射到Controller类。

HandlerAdapter

HandlerAdapter接口-处理请求映射

AnnotationMethodHandlerAdapter:通过注解,把请求URL映射到Controller类的方法上。

HandlerExceptionResolver

HandlerExceptionResolver接口-异常处理接口

  • SimpleMappingExceptionResolver通过配置文件进行异常处理。
  • AnnotationMethodHandlerExceptionResolver:通过注解进行异常处理。

ViewResolver

ViewResolver接口解析View视图。

UrlBasedViewResolver类 通过配置文件,把一个视图名交给到一个View来处理。

欢迎大家加入粉丝群:963944895,群内免费分享Spring框架、Mybatis框架SpringBoot框架、SpringMVC框架、SpringCloud微服务、Dubbo框架、Redis缓存、RabbitMq消息、JVM调优、Tomcat容器、MySQL数据库教学视频及架构学习思维导图

写在最后:

秃顶程序员的不易,看到这里,点了关注吧! 点关注,不迷路,持续更新!!!

转载于:https://juejin.im/post/5c497345f265da616e4cc29f

【本人秃顶程序员】SpringMVC工作原理详解相关推荐

  1. 【本人秃顶程序员】高级 Java 必须突破的 10 个知识点!

    ←←←←←←←←←←←← 快!点关注!!! 工作多少年了,还在传统公司写if / for 等简单的代码?那你就真的要被社会淘汰了,工作多年其实你与初级工程师又有多少区别呢?那么作为一个高级Java攻城 ...

  2. 【本人秃顶程序员】美女程序员观点:程序员最重要的非编程技巧

    ←←←←←←←←←←←← 快!点关注 这是来自一位美女程序员Ali Spittel的观点,至少可以看看美女喜欢和怎样的男程序猿打交道: 当我想与我希望的程序员合作时,我更多地考虑非技术技能,而不是技术 ...

  3. 【本人秃顶程序员】图解分布式架构的演进过程

    ←←←←←←←←←←←← 快!点关注!!! 一.什么是分布式架构 分布式系统(distributed system) 是建立在网络之上的软件系统. 内聚性: 是指每一个数据库分布节点高度自治,有本地的 ...

  4. 【本人秃顶程序员】我简历上的Java项目都好low,怎么办?

    ←←←←←←←←←←←← 快!点关注 这篇文章我们来聊一聊,在系统设计和项目经验这两块,应该如何充分的准备,才能拿出有技术含量的项目经验战胜跟你同台竞技的其他工程师,征服你的面试官,收获各种心仪的of ...

  5. 【本人秃顶程序员】使用Spring Cloud Stream和RabbitMQ实现事件驱动的微服务

    ←←←←←←←←←←←← 快!点关注 让我们展示如何使用Spring Cloud Stream来设计事件驱动的微服务.首先,Spring Cloud Stream首先有什么好处?因为Spring AM ...

  6. 【本人秃顶程序员】过年了,给亲朋好友解释“啥是程序员”

    ←←←←←←←←←←←← 快!点关注 一年一度的春节又到了,作为程序员的你是怎么告诉亲朋好友自己日常到底是做什么工作的呢? 程序员是一个新兴的职业,我在上大学以前不了解程序员到底是做什么的,对编程语言 ...

  7. java程序员秃顶,【本人秃顶程序员】使用Azure Function + Cognitive Services 实现图片自动化审核...

    ←←←←←←←←←←←← 快!点关注 假定我们正在运行某个应用程序,此应用程序需要用户在应用程序中提交大量图片文件,那么对于系统管理员来说手动审核这些图片是很消耗时间的,并且对于图片的审核也许并不是即 ...

  8. 【本人秃顶程序员】Java面试题集(意思意思)

    ←←←←←←←←←←←← 我都秃顶了,还不点关注! 一.什么是Spring MVC ?简单介绍下你对springMVC的理解? Spring MVC是一个基于MVC架构的 用来简化web应用程序开发的 ...

  9. 【本人秃顶程序员】分享一些数据结构与算法常用的算法技巧总结

    今天和大家讲讲,在做算法题时常用的一些技巧.对于平时没用过这些技巧的人,或许你可以考虑试着去看看在实践中能否用的上这些技巧来优化问题的解. 一.巧用数组下标 数组的下标是一个隐含的很有用的数组,特别是 ...

  10. java秃顶_【本人秃顶程序员】在Java中使用函数范式提高代码质量

    ←←←←←←←←←←←← 快!点关注 在一个范式和技术堆栈一直在变化的世界中,保持竞争力和提高生产力和质量的斗争有时候证明是一项挑战. 在本文中,我想首先展示一下函数编程(FP)的优势,特别是加强Ja ...

最新文章

  1. AlphaFold2成功秘诀:注意力机制取代卷积网络,预测准确性提升超30%
  2. 正确认识自己,把自己摆正位置
  3. iPad的无纸化办公和纯纸化办公的区别和使用场景
  4. python中的单下划线和双下划线_python中的单下划线和双下划线
  5. oracle 多个实例互相切换实例
  6. 用SwiftGen管理UIImage等的String-based接口
  7. sql replace into 与 insert into
  8. 《设计模式详解》创建型模式 - 工厂模式
  9. 书海拾贝|开发艺术探索之 android 的消息机制
  10. 如何限定apt-get使用IPv4或IPv6协议下载
  11. 拉肚子差评回复模板_外卖差评回复模板
  12. 法语计算机相关书籍,法语网络计算机相关词汇
  13. 滴滴Booster移动APP质量优化框架 学习之旅
  14. 推荐系统实践(三)ICF和UCF
  15. security整合oauth2(jwt非对称加密):For MAC signing you do not need to specify the verifier key separately...
  16. 道阻且长,行则将至;行而不辍,未来可期。
  17. PIC16F73-I/SO代理
  18. matlab使用CVX求解优化问题时,如果变量搜索空间过大,导致求解的数值解相当不准确,通过变量替换,缩小搜索空间
  19. android裁剪图片
  20. 华硕系统安装程序正在启动服务器,华硕电脑用u盘如何装系统win7

热门文章

  1. mysql+centos7+主从复制
  2. Spring 定时器的使用(task)
  3. Java入门——第九天
  4. JZOJ 1714. 小x的三角形(triangles.pas/cpp)
  5. go语言mongdb管道使用
  6. Html辅助方法(分页、下拉框)
  7. 一个很方便使用十六进制的颜色值的宏
  8. 基本数据结构----顺序表
  9. oracle函数 TO_MULTI_BYTE(c1)
  10. C,LINUX,数据结构部分