SpringMVC核心源码解析(一)

传统的web编程

在了解SpringMVC源码之前,我们需先关注SpringMVC解决了什么问题,在原来的web编程中,我们会基于servlet实现web编程,我们简单回顾下,首先新建一个类实现HttpServlet

public class MyHttpServlet extends HttpServlet {

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   // 写逻辑
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    super.doGet(req, resp);
}

}
然后在web.xml文件对我们配置我们的类

<web-app>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>MyHttpServlet </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/MyHttpServlet </url-pattern>
</servlet-mapping>

</web-app>
简单介绍下它的工作流转,其实很简单就是通过我们配置的url-pattern找到servlet-name,再根据servlet-name找到我们继承HttpServlet的MyHttpServlet类,了解过web编程方式的读者们一定都知道,这种东西带来的开发效率太低,重复工作太多,并且代码结构混乱,难以维护,那么Spring又是如何解决这样的问题呢?

SpringMVC应用

相信大家对SpringMVC的应用都不太陌生,我们还是先简单用实例的方式介绍,创建一个UserController 类,然后加上注解@Controller

@Controller
public class UserController{

@RequestMapping("/home")
public String home(){
    return "home";
}

}
然后在web.xml配置

<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在新建一个spring-mvc.xml作为mvc的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

<!--开启切面编程自动代理-->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>application/json;charset=UTF-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>
<!--包扫描-->
<context:component-scan base-package="com.*"/>
<!--开启注解扫描-->
<mvc:annotation-driven/>

</beans>
当然这里还需要对Spring进行配置,对于Spring的文件配置就不说了,这里重点对SpringMVC进行描述,好了我们将一些SpringMVC必要的配置搞定后运行一下,在浏览器注入http://localhost:8080/user

通过运行结果我们可以看出我们的方法已经成功映射到了我们的url链接上,那么我们对比一下传统的Servlet和SpringMVC,随着业务的繁琐和复杂,你会发现传统的Servlet带来的问题,以及SpringMVC的便利,相信但凡是接触过这两者的区别的人都有所认同,那么SpringMVC是如何做到如此简便就完成了Servlet操作的呢?

SpringMVC原理

我们思考一下,在传统的Servlet中我们是通过创建不同的类来区分不同的url请求,如果采用SpringMVC后,只需要在方法或类上加上@RequestMapping()注解,就能实现对传统创建类的方式运转,这样的框架设计极其简化了在开发时候复杂操作,也符合项目分层设计,个人认为Spring的成功原因之一就在于此,好了废话了那么多,下面就简单介绍下SpringMVC设计的基本思路。

在SpringMVC之前,其实还有一种框架叫Struct,可能现在大家都没怎么接触这哥们儿了,但有些古董项目基于架构庞大,还是依旧采用的Struct,为什么会提到Struct呢?笔者认为Struct和我们传统的Servlet很像,都是基于配置和类进行关联,然后每一个Servlet都是一个单独的对象,举个例子我们系统有个登录接口,然后采用传统的Servlet或者Struct就会创建一个登录类然后配置映射到我们的url上,就像上文传统web编程的实例一样,然后Tomcat容器就会根据你的每一个类创建一个单独的Servlet,然后如果你有10个功能,那么就是十个Servlet,每一次访问、跳转、重定向其实对JVM来说都是不小的开销,因为总是存在对象创建和销毁。这个时候Spring看不下去了,Spring就推出了SpringMVC,后面Struct虽然出现了Struct2但依旧没有摆脱它原来带来的问题,甚至还出现了许多漏洞,SpringMVC就逐渐占领了市场,那么SpringMVC是怎样设计的呢?我们来看一张图

这里笔者详细介绍一下, 我们再次对比一下原生的Servlet配置和SpringMVC配置的web.xml

传统的Servlet配置

<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>MyHttpServlet </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/MyHttpServlet </url-pattern>
</servlet-mapping>

SpringMVC的web.xml配置信息

<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
我们通过对比后可以看出,SpringMVC将一个普通的类org.springframework.web.servlet.DispatcherServlet和/映射,目的就是想通过自己创建的DispatcherServlet作为一个全局的Servlet,然后用这个全局的Servlet来匹配请求和方法,如果还不明白结合上面的图一起自行思考,那么SpringMVC通过这种方式就实现了Servlet单例的方式,因为所有请求都是同一个类DispatcherServlet作为Servlet处理请求,好了,本章内容结束,下一章节将对SpringMVC底层源码进行分析。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容