美文网首页
SpringMVC核心源码解析(一)

SpringMVC核心源码解析(一)

作者: 七天0 | 来源:发表于2022-05-07 14:01 被阅读0次

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

相关文章

网友评论

      本文标题:SpringMVC核心源码解析(一)

      本文链接:https://www.haomeiwen.com/subject/sjqxurtx.html