Spring MVC简单原理

Spring MVC简单原理

针对有Java Web基础、Spring基础和Spring MVC使用经验者,文章比较简单,权当自己的一个总结和备忘吧。

前言

目前基于Java的web后端,Spring生态应该是比较常见了。虽然现在流行前后端分离,MVC和后端模板渲染越来越少,后端专注向前端提供数据接口。但由于笔者维护着一个老项目,既有JSP技术也有只返回JSON的接口,两者都是基于Spring MVC这一套技术实现的,所以暂且觉得了解一下Spring MVC原理还是有所裨益的。

Spring MVC工作流

想必大家第一次学习Spring MVC时都见过这张图

看完这张图,Spring MVC的工作流基本是一目了然了。建好工程然后web.xml里配个DispatcherServlet(甚至连web.xml都不需要配置,直接通过Java类和@Configuaration进行配置),注解@Controller, @RequestMapping, @Service等等一顿注解搞起来,在IDE中把Tomcat配好,OK,一个Spring MVC的Hello World就跑起来了。问起Spring MVC的原理,我也能按着上图工作流巴拉几句。

然而,与其说以上是Spring MVC的原理不如说是MVC的模型。Spring MVC怎么就知道把一个请求路由到对应Controller中方法的呢?方法返回了一个ModelAndView对象甚至是一个视图名String,框架带着Model和视图名找到视图(比如最常见的jsp)后怎么搞呢?半路出家的笔者来,可以说是相当好奇了。

从servlet、web.xml和WEB-INF说起

Servlet

Java的Servlet我就不赘述了,直接看类的注释

A servlet is a small Java program that runs within a Web server.Servlets receive and respond to requests from Web clients, usually across HTTP

Servlet只是一个规范,必须部署到Servlet容器中才能工作,当然本文说的肯定是HttpServlet,所以常用的容器也就是Tomcat、Jetty等。

先看Servlet接口,每个方法的注释请参见源码

public interface Servlet {

    public void init(ServletConfig config) throws ServletException;

    public ServletConfig getServletConfig();

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

    public String getServletInfo();

    public void destroy();
}

其中init方法在Servlet准备对外提供服务时被容器调用,并且整个生命周期中只调用一次,destroy方法当然就是结束时调用了,service方法处理ServletRequest并响应。

web.xml

上面说到把Servlet部署到Servlet容器中后,Servlet就可以接受请求了,那容器怎么知道哪个请求对应哪个Servlet?

OK,我们的web.xml登场了。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>com.foo.bar.SomeServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>/some/url</url-pattern>
    </servlet-mapping>
</web-app>

如上,最简单的一个web.xml描述文件,描述了什么呢?应该都懂,SomeServlet这个Servlet会处理URL为/some/url的请求,这个SomeServlet大概长这样

public class SomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("hello boys");
        writer.flush();
        writer.close();
    }
}

GET someHost:port/some/url时,就会返回hello boys了。不难想象,请求多的话,得在web.xml中servlet的节点将越来越多,维护起来也是个体力活儿(当然用xml维护的Spring MVC配置文件也没少多少,不过维护起来轻松一些,因为结合了Spring bean,下面再讲)。

以上应该是对Servlet相关最简单的描述了。

Spring容器管理bean

这个用过没用过Spring的应该都有所了解,说一下我自己的理解

核心就是DI,通过Spring这个IOC容器来管理各个Bean之间的依赖关系,通过Spring在启动时来注入依赖,而不是在写代码时就new出来。

这里面我觉得比较重要的几个类,也是我认为看Spring代码时比较好串联起来的几个类:

  • BeanDefinition: Spring的定义,最常见的我个人认为最好理解的也就是Xml中定义的bean,此处膜拜一下Spring预留的扩展点,要不然dubbo的bean怎么能通过Spring容器管理呢对吧,此处以后再说。
  • BeanFactory: 好理解,产生Bean的工厂,不多说自己看代码。
  • ApplicationContext: Spring的上下文容器,基本用的就是它,暂时把它当成黑箱,所有的bean从这里getBean获取就行了,其余自行看代码。

DispatcherServlet

好,终于到Spring MVC了,先上一个大家都见过的web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</webapp>

注意到几个点:

  • DispatcherServlet这个servlet接管了所有的请求(servlet-mapping的配置)
  • servlet配置里还有个load-on-startup,且值为1
  • init-param这里配置了一个参数contextConfigLocation,其值就是Spring bean的配置文件

DispatcherServlet接管了所有请求,OK,看到这里大家估计也都明白了,是在这个servlet里的service方法里根据不同url找到不同的controller来处理的;load-on-startup这个参数规定,如果值大于0,会在启动时由容器初始化,并且值越小初始化顺序越靠前;init-param名字已经很直白了,表示这个servlet可以配置的参数,对该servlet可见(对应的还有个context-param,对所有servlet可见,web.xml里还有其他一些可配置的参数,有兴趣可以自行查阅),contextConfigLication的值就是多个定义bean的xml配置文件。

讲完这些,大家猜应该八九不离十了,总结起来就是一句话:

Servlet容器启动时调用DispatcherServlet中init方法,同时依托Spring,初始化所有bean,并保存一个url到handler之间的映射

至于映射关系就好定义了,xml配置、@RequestMapping,都是具体的实现。当然我这是简单粗暴的总结,里面细节性的问题都跳过了不过你自己在init方法里打个断点,debug跟一下,一步一步就摸清全部流程了。

文章比较短也比较简单,大家也可能都了解,但我觉得这几个点对理清整个流程还是有帮助的。提出的几个问题也没解答,我只能说答案都在代码里,跟一下全明白。写的不好大家也别笑,多给我提提建议,大家相互进步就OK。

原文地址:https://www.cnblogs.com/dirac/p/8546864.html

时间: 2024-10-10 15:42:07

Spring MVC简单原理的相关文章

spring Mvc 执行原理 及 xml注解配置说明 (六)

Spring MVC 执行原理 在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet 处理; 一个Spring MVC工程里,可以配置多个的 dispatcherServlet ,每个 DispatcherServlet 可以对应多个的 HandlerMapping ,每个 HandlerMapping 可以有自己的 Interceptor (拦截器). 1. 请求首先 由 前端 DispatcherServlet 捕获: 2. Disp

【转】spring Mvc 执行原理 及 xml注解配置说明

Spring MVC 执行原理 在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet 处理; 一个Spring MVC工程里,可以配置多个的 dispatcherServlet ,每个 DispatcherServlet 可以对应多个的 HandlerMapping ,每个 HandlerMapping 可以有自己的 Interceptor (拦截器). 1. 请求首先 由 前端 DispatcherServlet 捕获: 2. Disp

Spring MVC:原理与使用

本人上一篇博文提到了Spring的注入功能,这样在存在对象依赖(具体意思可见上一篇博文)的时候就不用自己生成一个对象了,特别是对于较多的无状态对象的时候,这个特别方便,加上Spring提供的用xml配置文件和代码注解两种方式,使得使用更加灵活.然而spring的功能远不止如此,Spring的强大功能其实还在于做Java后台框架,即Spring MVC,把后台的逻辑和和视图解耦分离,方便使用与扩展,特别是在大型项目中很有用. PS:卖个自己的广告,上一篇博文<Spring注入:配置与注解> (如

spring mvc 工作原理

SpringMVC框架介绍 1) Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架.通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术.Velocity.Til

Spring MVC — @RequestMapping原理讲解-1

转载地址 :http://blog.csdn.net/j080624/article/details/56278461 为了降低文章篇幅,使得文章更目标化,简洁化,我们就不例举各种@RequestMapping的用法等内容了. 具体请点击查看@RequestMapping的用法 文章主要说明以下问题: Spring怎样处理@RequestMapping(怎样将请求路径映射到控制器类或方法) Spring怎样将请求分派给正确的控制器类或方法 Spring如何实现灵活的控制器方法的 在Spring 

spring mvc简单介绍xml版

spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServlet:负责接受所有的请求,就像普通的servlet一样,此接口只是简单的负责处理接受请求. 2.HandlerMapping:当接受到请求后,由此组件负责解析请求,知道该请求要访问那个具体的Controller(具体的Servlet). 3.HandlerAdaper:负责调用具体的Controll

Spring MVC 简单入门

web.xml 配置: <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <description>加载/WEB-INF/spring-mvc/目录下的所有XML作为Spring MVC的

Spring MVC工作原理

Spring MVC工作流程图 图一 图二  Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获: 2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI).然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回: 3.

Spring MVC(一)Spring MVC的原理

1.Spring MVC的目的 构建向Spring框架那样灵活和松耦合的Web应用程序. 2.Spring MVC中如何处理Request? 每当用户在Web浏览器中点击链接或者提交表单时,Request就开始工作了. 从离开浏览器开始到获取响应返回,Request会在经历过的每一站留下一些信息,也会获取一些信息. DipatcherServlet--前端控制器Servlet,负责将Request发送给Spring MVC的Controller: Handler Mapping--处理器映射,应