前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速学习-拦截器运行流程图解

快速学习-拦截器运行流程图解

作者头像
cwl_java
发布2020-02-19 15:50:53
6400
发布2020-02-19 15:50:53
举报
文章被收录于专栏:cwl_Javacwl_Java

第11章 运行流程图解

11.1 流程图

在这里插入图片描述
在这里插入图片描述

11.2 Spring工作流程描述

  1. 用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获;
  2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI): 判断请求URI对应的映射 ① 不存在: 再判断是否配置了mvc:default-servlet-handler: 如果没配置,则控制台报映射查找不到,客户端展示404错误 如果有配置,则执行目标资源(一般为静态资源,如:JS,CSS,HTML) ② 存在: 执行下面流程
  3. 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
  4. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。
  5. 如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法【正向】
  6. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作: ① HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息 ② 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等 ③ 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等 ④ 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
  7. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
  8. 此时将开始执行拦截器的postHandle(…)方法【逆向】
  9. 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet,根据Model和View,来渲染视图
  10. 在返回给客户端时需要执行拦截器的AfterCompletion方法【逆向】
  11. 将渲染结果返回给客户端

11.3 源码解析

11.3.1 搭建环境

  1. 拷贝jar包
代码语言:javascript
复制
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
commons-logging-1.1.3.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
  1. 配置文件web.xml
代码语言:javascript
复制
<servlet>
	<servlet-name>springDispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:springmvc.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>springDispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>
  1. 配置文件springmvc.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 
<!-- 设置扫描组件的包 -->
<context:component-scan base-package="com.atguigu.springmvc"/>
 
<!-- 配置视图解析器 -->
<bean id="internalResourceViewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
 
</beans>

11.3.2 完成HelloWorld

  1. 页面链接
代码语言:javascript
复制
<a href="helloworld">Hello World</a>
  1. 控制器方法
代码语言:javascript
复制
@Controller
public class HelloWorldHandler { 
    @RequestMapping("/helloworld")
    public String testHello(){ 
        System.out.println("Hello,SpringMVC..."); 
        return "success";
    } 
}
  1. 成功页面:/views/success.jsp
代码语言:javascript
复制
<h3>Success Page</h3>

11.3.3 Debug实验

  1. 正常流程,运行出结果
  2. 没有配置<mvc:default-servlet-handler/>,测试,直接报404 ① http://localhost:8080/SpringMVC_09_WorkFlow/helloworld2
代码语言:javascript
复制
四月 20, 2016 11:53:19 上午 org.springframework.web.servlet.PageNotFound noHandlerFound
警告: No mapping found for HTTP request with URI [/SpringMVC_09_WorkFlow/helloworld2] in DispatcherServlet with name 'springDispatcherServlet'

② http://localhost:8080/SpringMVC_09_WorkFlow/test.html

代码语言:javascript
复制
四月 20, 2016 11:54:16 上午 org.springframework.web.servlet.PageNotFound noHandlerFound
警告: No mapping found for HTTP request with URI [/SpringMVC_09_WorkFlow/test.html] in DispatcherServlet with name 'springDispatcherServlet'
  1. 配置<mvc:default-servlet-handler/>,测试,会去查找目标资源
  2. 测试,依然发生错误,这时,需要配置:<mvc:annotation-driven/>,否则,映射解析不好使。
在这里插入图片描述
在这里插入图片描述

11.3.4 Debug流程分析

  1. HandlerExecutionChain mappedHandler;包含了拦截器和处理器方法; DispatcherServlet L902 916
代码语言:javascript
复制
org.springframework.web.servlet.HandlerExecutionChain
Handler execution chain, consisting of handler object and any handler interceptors. Returned by
 HandlerMapping's HandlerMapping.getHandler method.
在这里插入图片描述
在这里插入图片描述
  1. HandlerMapping
代码语言:javascript
复制
org.springframework.web.servlet.HandlerMapping
Interface to be implemented by objects that define a mapping between requests and handler objects. 
This class can be implemented by application developers, although this is not necessary, as org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping and org.springframework.web.servlet.handler.SimpleUrlHandlerMapping are included in the framework. The former is the default if no HandlerMapping bean is registered in the application context. 
HandlerMapping implementations can support mapped interceptors but do not have to. A handler will always be wrapped in a HandlerExecutionChain instance, optionally accompanied by some HandlerInterceptor instances. The DispatcherServlet will first call each HandlerInterceptor's preHandle method in the given order, finally invoking the handler itself if all preHandle methods have returned true. 
The ability to parameterize this mapping is a powerful and unusual capability of this MVC framework. For example, it is possible to write a custom mapping based on session state, cookie state or many other variables. No other MVC framework seems to be equally flexible. 
Note: Implementations can implement the org.springframework.core.Ordered interface to be able to specify a sorting order and thus a priority for getting applied by DispatcherServlet. Non-Ordered instances get treated as lowest priority.
  1. 没有配置<mvc:default-servlet-handler/><mvc:annotation-driven/>,发送一个不存在资源的请求路径,mappedHandler为null http://localhost:8080/SpringMVC_09_WorkFlow/helloworld2
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  1. 配置mvc:default-servlet-handler/mvc:annotation-driven/,发送一个不存在资源的请求路径 http://localhost:8080/SpringMVC_09_WorkFlow/helloworld2 mappedHandler不为null,原因是当循环simpleUrlHandlerMapping时,当做静态资源处理
在这里插入图片描述
在这里插入图片描述

11.3.5 断点

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第11章 运行流程图解
    • 11.1 流程图
      • 11.2 Spring工作流程描述
        • 11.3 源码解析
          • 11.3.1 搭建环境
          • 11.3.2 完成HelloWorld
          • 11.3.3 Debug实验
          • 11.3.4 Debug流程分析
          • 11.3.5 断点
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档