springMVC 源码级别总结原理,DispatcherServlet核心方法

前言

springMVC自我总结

本次maven:

	<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.3.7.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency>

1.先上图

(这个是百度的,这个图好多网友都画了,都是一个意思,随便拿一个好看的,以便下面能写的通顺)
在这里插入图片描述

2.工作流程

以下每一步,对应上图的每一步,都是我自己的理解,如果有误,还请指出

1.用户发来请求,由于在web.xml中配置如下,请求进入了请求处理器:DispatcherServlet
在这里插入图片描述
2.在请求处理器中,第一步便是找到合适的控制器,即图中的第二步,对应源码解释:

 DispatcherServlet的doService方法的doDisPatch方法是核心逻辑所在,在doDispatch方法中,有一行是mappedHandler = this.getHandler(processedRequest);这个方法中有个HandlerMapping,我们一般叫这个为处理器,他有两个实现类第一个是:BeanNameUrlHandlerMapping,代表如果是XML配置方式的控制器,就用这个XML就是自定义Controller类实现org.springframework.web.servlet.mvc.Controller.Controller接口,然后在配置文件中配置bean标签的方式第二个是:RequestMapppingHandlerMaping,代表注解方式的控制器,就用这个注解方法就是在自定义Controller类上加注解@Controller,方法上加@RequestMapping的方式看源码包中,这两个实现类也是初始化的时候就定义好的,在源码包的DispatcherServlet.properties中这个便是找到合适的控制器,并返回返回的是HanderExecuteChain对象,这个对象包括Handler对象和拦截器数组,形成一个链返回

3.调用Handler,其实就是找到合适的处理器

同样在doDispatch方法中,有一行是:HandlerAdapter err1 = this.getHandlerAdapter(mappedHandler.getHandler());
这个就是选择到了合适的处理器,也用到了适配器模式HandlerAdapter 有三个实现:
第一个是:HttpRequestHanderAdapter
第二个是:SimpleControllerHanderAdapter
第三个是:AnnotationMethodHanderAdapter第一个和第二个对应的是XML的配置方式
第三个对应的是注解的配置方式

4.处理业务逻辑

同样在doDispatch方法中,有一行是:err = err1.handle(processedRequest, response, mappedHandler.getHandler());
这个就是处理业务逻辑了,这个方法会去执行我们自己写的Controller
前面两步,一个是找到合适的控制器,一个是找到合适的处理器,其实都是为了这一步做的,
之所以前面分成两步,我看就是为了解耦,让代码更加灵活,有扩展性

5.返回ModelAndView

上一步返回的即是ModelAndView对象

6,7,8.调用视图解析器,将model数据传给view

同样在doDispatch方法中,有一行是:this.processDispatchResult(processedRequest, response, mappedHandler, err, (Exception)dispatchException);这个方法下有个方法是:this.render(mv, request, response);这个方法下有个方法是: view = this.resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
这个方法下,才是真正的视图解析ViewResolver viewResolver = (ViewResolver)var5.next();view = viewResolver.resolveViewName(viewName, locale);
返回view这个要配合配置文件
一般我们都会在配置文件中配置视图解析器<!-- 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 配置视图解析器的前缀和后缀 --><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value=".jsp"></property></bean>在自定义Controller中,返回对应的jsp,也就是这里起的作用,前缀是全路径,后缀是视图类型
假如自定义Controller类中返回值为test,那么根据视图解析器可得将要跳转的页面路径为:/WEB-INF/jsp/test.jsp

3.springMVC的一些总结

1.先说与struts2的对比

如果你做过项目的重构,将struts2的架构转移到springMVC架构上,你就会深深的感受到这两个框架的区别了
感受最多的,就是struts2太多的成员变量了,struts2是多例的,所以struts2中的成员变量简直不能太多
而springMVC默认是单例的,这个时候所有controller的方法入参都要一个一个捋出来,真的不好玩
而springMVC保持单例,也是业界认可的,就是竟可能的就是使用单例
因为这样可以减少创建对象和回收对象的开销.也就是说,如果controller的类变量和实例变量最好以方法形参声明,不要以类变量和实例变量声明,这样也可以避免线程安全问题。当然,有了这个,struts2的值域的概念,也可以忘记了

2.spring和springMVC,都是容器的概念

spring是父容器,springMVC是子容器
父容器中拿不到子容器的bean
子容器可以拿到父容器的bean

4.附上测试代码

web.xml

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springconfig.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

springconfig.xml(这个应该是springmvc.xml,这样意思才算对,懒得改了,看懂就行)

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--扫描包--><context:component-scan base-package="com.zs"></context:component-scan><!--开启springMVC注解--><mvc:annotation-driven></mvc:annotation-driven><!-- 配置视图解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 配置视图解析器的前缀和后缀 --><property name="prefix" value="/WEB-INF/jsp/"></property><property name="suffix" value=".jsp"></property></bean><bean id="data" class="java.util.Date"></bean><bean name="/test1" class="com.zs.MyController"></bean></beans>

MyController.java(基于XML配置的)

package com.zs;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {System.out.println("my controller run..............");return null;}
}

MyController2.java(基于注解配置的)

package com.zs;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Controller
public class MyController2 {@RequestMapping("/test2")public String handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {System.out.println("my controller2 run..............");return "index2";}
}

项目结构:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLite3中的数据类型

一、概述 大多数的数据库引擎&#xff08;到现在据我们所知的除了sqlite的每个sql数据库引擎&#xff09;都使用静态的、刚性的类型&#xff0c;使用静态类型&#xff0c;数据的类型就由它的容器决定&#xff0c;这个容器是这个指被存放的特定列。 Sqlite使用一个更一般的动态类…

关于iOS7里的JavaScriptCore framework

在iOS7沸沸扬扬的扁平化论战之外&#xff0c;WWDC 2013还是公布了很多让开发者小兴奋的点&#xff0c;其中包括多任务加强支持background fetch和transfer&#xff0c;近场通信的AirDrop和p2p&#xff0c;以及游戏控制器和游戏中心的加强&#xff1b;当然还包括了让web开发同学…

深入浅出Fetch API

多年来&#xff0c;XMLHttpRequest一直是web开发者的亲密助手。无论是直接的&#xff0c;还是间接的&#xff0c; 当我们谈及Ajax技术的时候&#xff0c;通常意思就是基于XMLHttpRequest的Ajax&#xff0c;它是一种能够有效改进页面通信的技术。 Ajax的兴起是由于Google的Gmail…

[设计模式] ------ 简单工厂模式

简单工厂模式 不同类型下创建对应的不同的对象&#xff0c;得到不同的结果&#xff0c;就叫简单生产模式 比如 定义一个接口&#xff0c;叫A&#xff0c;里面有方法a&#xff0c;返回int类型 类B1实现A接口&#xff0c;也实现a方法&#xff0c;里面做的是加法运算 类B2实现…

第19章总结

一.Java绘图类 1.Graphics类 Graphics类是所有图形上下文的抽象基类&#xff0c;它允许应用程序在组件以及闭屏图像上进行绘制。Graphics类封装了Java支持的基本绘图操作所需的状态信息&#xff0c;主要包括颜色、字体、画笔、文本、图像等。 2.Graphics2D类 Graphics2…

RSA公钥文件(PEM)解析

公钥语法为&#xff1a; RSAPublicKey :: SEQUENCE { modulus INTEGER, //RSA合数模n publicExponent INTEGER //RSA公开幂e } 说明&#xff1a; 1.此语法中的modulus和publicExponent&#xff0c;提取自对应私钥中的同名域值。 2.PKCS1和PKCS8的公钥文件是一样的&#xff…

RSA私钥文件(PEM-PKCS#1)解析

在PKCS#1 RSA算法标准中定义RSA私钥语法 RSAPrivateKey :: SEQUENCE { version Version, //版本 modulus INTEGER, // RSA合数模 n publicExponent INTEGER, //RSA公开幂 e privateExponent INTEGER, //RSA私有幂 d prime1 INTEGER, //n的素数因子p prime2 INTEGER, //n的…

[分布式] ------ 全局唯一id生成之雪花算法(Twitter_Snowflake)

雪花算法&#xff08;Twitter_Snowflake&#xff09; 我们知道&#xff0c;分布式全局唯一id的生成&#xff0c;一般是以下几种&#xff1a; 基于雪花算法生成基于数据库基于redis基于zookeeper 本文说下雪花算法&#xff0c;后面附源码以及测试代码。 如下图&#xff1a; …

非对称加解密交互故事

1.鲍勃有两把钥匙&#xff0c;一把是公钥&#xff0c;另一把是私钥。 2.鲍勃把公钥送给他的朋友们—-帕蒂、道格、苏珊—-每人一把。 3.苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密&#xff0c;就可以达到保密的效果 4.鲍勃收信后&#xff0c;用私钥解密&#xff0…

Sqlite3中replace语句用法详解

在本例中使用如下数据库表&#xff1a; &#xff08;图 1&#xff09; 该表的表名为student&#xff0c; 存储学生信息。 所有字段的数据类型都是TEXT 。 其中id和name作为复合主键。 email字段加上了唯一约束。建表语句如下&#xff1a; CREATE TABLE IF NOT EXISTS student …

[分布式一致性协议] ------ raft协议的解释与理解

前言 在分布式系统中&#xff0c;为了保证容错性&#xff0c;一般会维护多个副本集群&#xff0c;提高系统的高可用&#xff0c;但与之带来的问题就是多个副本的一致性&#xff08;consensus&#xff09;问题。 我们认为&#xff0c;对于一个具有一致性的的集群中&#xff0c;…

利用.dSYM和.app文件准确定位Crash位置

当发布到iPhone上的应用程序Crash之后&#xff0c;iPhone会自动生成一个Crash Log&#xff08;*.crash&#xff09;&#xff0c;这个文件包含了一些有用的调试信息&#xff0c;但对于堆栈&#xff0c;它只记录的函数地址&#xff0c;而无法显示函数名。函数名保存在一个叫dSYM的…

MVPVM模式介绍

一、概述MVPVM即&#xff1a;Model-View-Presenter-ViewModel。此模式是MVVM和MVP模式的结合体。但是交互模式发生了比较大的变化。MVVM参考本博客文章&#xff1a;iOS-MVVM-模式介绍MVP参考本博客文章&#xff1a;MVP模式介绍 二、原理&#xff1a;Presenter同时持有View、Mod…

分组密码的工作模式

一、理论基础1.概述密码学中&#xff0c;块密码的工作模式允许使用同一个块密码密钥对多于一块的数据进行加密&#xff0c;并保证其安全性。块密码自身只能加密长度等于密码块长度的单块数据&#xff0c;若要加密变长数据&#xff0c;则数据必须先被划分为一些单独的密码块。通…

PBOC3.0中使用的国密SM2算法

一、知识准备 PBOC3.0规范就是《中国金融集成电路&#xff08;IC&#xff09;卡规范》3.0版本。SM2是国密局推出的一种他们自己说具有自主知识产权的非对称商用密码算法。本身是基于ECC椭圆曲线算法的&#xff0c;所以要讲SM2, 先要弄懂ECC。 完全理解ECC算法需要一定的数学功底…

Markdown入门

Markdown 是一种轻量级的「标记语言」&#xff0c;它的优点很多&#xff0c;目前也被越来越多的写作爱好者&#xff0c;撰稿者广泛使用。看到这里请不要被「标记」、「语言」所迷惑&#xff0c;Markdown 的语法十分简单。常用的标记符号也不超过十个&#xff0c;这种相对于更为…

mysql数据库支持emoji表情的详解

mysql存储emoji表情的时候&#xff0c;就会报错&#xff0c;如下&#xff1a; Error updating database. Cause: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x98\x8A\xF0\x9F…’ for column ‘这是我表中的字段’ at row 1 初步定位是我的数据库是utf8编码…

编程规范:长函数的思考

在工作&#xff0c;我们应该都不想看到非常的长函数。对于一个运行5年左右的项目&#xff0c;极有可能出现这种情况。由于长函数的长、if/else嵌套&#xff0c;导致代码的可读性非常差&#xff0c;这对于项目的维护和开发带来了极大的困难。所以我们应该避免写长函数&#xff0…

用redis实现延迟队列

现在在用的redis实现延迟队列的主流程

maven更新快照不起作用的解决方法

问题&#xff1a;maven的快照包更新后&#xff0c;调用方使用idea点下面这个地方更新maven&#xff0c;并没有拉到最新的快照 解决方法1 删除本地仓库的快照包&#xff0c;再重新拉一次 解决方法2 下图&#xff0c;这里点进去 下图&#xff0c;这个勾上就行了&#xff0c;再…