SpringMVC核心源码解析(一)

​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底层源码进行分析。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值