摸透Spring MVC真正如何工作核心原理(part:1)

通过优锐课核心Spring MVC学习笔记中,我们可以看到Spring MVC中包含的功能可以在Web应用程序中发挥巨大作用的强大功能。

这是Spring Web MVC的强大功能和内部工作的深入研究,它是Spring Framework的一部分。

1、项目设置

在整篇文章中,将使用最新,最出色的Spring Framework5。我们在这里重点介绍Spring的经典Web堆栈,该框架的第一版已经提供了该框架,但仍然是构建Web应用程序的主要方式 与Spring。
对于初学者而言,要设置测试项目,你将使用Spring Boot及其一些初学者依赖项; 你还需要定义父级:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.M5</version>
    <relativePath/>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

请注意,为了使用Spring 5,你还需要使用Spring Boot2.x。 在撰写本文时,这是一个里程碑版本,可在Spring Milestone存储库中找到。 让我们将此存储库添加到你的Maven项目中:

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

你可以在Maven Central上签出Spring Boot的当前版本。

2、样例项目

为了了解Spring Web MVC的工作原理,你将实现一个带有登录页面的简单应用程序。 要显示登录页面,请创建一个@Controller注释的类InternalController,该类具有上下文根的GET映射。
hello()方法是无参数的。 它返回一个String,Spring MVC将其解释为视图名称(在我们的示例中为login.html模板):

import org.springframework.web.bind.annotation.GetMapping;
@GetMapping("/")
public String hello() {
    return "login";
}

要处理用户登录,请创建另一个方法来处理带有登录数据的POST请求。 然后,根据结果将用户重定向到成功页面或失败页面。
请注意,login()方法接收域对象作为参数并返回ModelAndView对象:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
@PostMapping("/login")
public ModelAndView login(LoginData loginData) {
    if (LOGIN.equals(loginData.getLogin()) 
      && PASSWORD.equals(loginData.getPassword())) {
        return new ModelAndView("success", 
          Collections.singletonMap("login", loginData.getLogin()));
    } else {
        return new ModelAndView("failure", 
          Collections.singletonMap("login", loginData.getLogin()));
    }
}

ModelAndView是两个不同对象的持有人

模型–用于呈现页面的数据的键值映射

视图–页面的模板,其中填充了来自模型的数据

为了方便起见,将它们结合在一起,以便控制器方法可以一次返回它们。
要渲染HTML页面,请使用Thymeleaf作为视图模板引擎,该引擎与Spring紧密集成在一起。

3、Servlet作为Java Web应用程序的基础

因此,当你在浏览器中输入http:// localhost:8080 /并按Enter键,请求到达Web服务器时,实际发生了什么? 你如何从该请求到在浏览器中看到Web表单?
由于该项目是一个简单的Spring Boot应用程序,因此你可以通过Spring5Application运行它。
Spring Boot默认使用Apache Tomcat。 因此,运行该应用程序,你可能会在日志中看到以下信息:

2017-10-16 20:36:11.626  INFO 57414 --- [main] 
  o.s.b.w.embedded.tomcat.TomcatWebServer  : 
  Tomcat initialized with port(s): 8080 (http)
2017-10-16 20:36:11.634  INFO 57414 --- [main] 
  o.apache.catalina.core.StandardService   : 
  Starting service [Tomcat]
2017-10-16 20:36:11.635  INFO 57414 --- [main] 
  org.apache.catalina.core.StandardEngine  : 
  Starting Servlet Engine: Apache Tomcat/8.5.23

由于Tomcat是Servlet容器,因此发送到Tomcat Web服务器的每个HTTP请求自然都由Java Servlet处理。 因此,毫无疑问,Spring Web应用程序的入口点是servlet。

简单地说,Servlet是任何Java Web应用程序的核心组件; 它是低级的,并且不会以特定的编程模式(例如MVC)强加太多。
HTTP Servlet只能接收HTTP请求,以某种方式处理它,然后将响应发送回去。

并且,从Servlet 3.0 API开始,你现在可以超越XML配置并开始利用Java配置(有轻微的限制)。
并且,从Servlet 3.0 API开始,你现在可以超越XML配置并开始利用Java配置(有轻微的限制)。

4、DispatcherServlet是Spring MVC的心脏

作为Web应用程序开发人员,我们真正想要做的是抽象出以下乏味和样板任务,并专注于有用的业务逻辑:

将HTTP请求映射到某种处理方法

将HTTP请求数据和标头解析为数据传输对象(DTO)或域对象
模型-视图-控制器交互

从DTO,域对象等生成响应。

Spring DispatcherServlet正是提供了这一点。 它是Spring Web MVC框架的核心。 该核心组件接收对你的应用程序的所有请求。

如你所见,DispatcherServlet非常可扩展。 例如,它允许你插入不同的现有适配器或新适配器来完成许多任务:

将请求映射到应该处理该请求的类或方法(HandlerMapping接口的实现)

使用特定模式处理请求,例如常规servlet,更复杂的MVC工作流程或仅POJO bean中的方法(HandlerAdapter接口的实现)

按名称解析视图,允许你使用不同的模板引擎,XML,XSLT或任何其他视图技术(ViewResolver接口的实现)

通过使用默认的Apache Commons文件上传实现或编写自己的MultipartResolver来解析多部分请求

使用任何LocaleResolver实现解析语言环境,包括cookie,会话,Accept HTTP标头或任何其他确定用户期望的语言环境的方法

5、HTTP请求的处理

首先,让我们跟踪对简单HTTP请求的处理,以处理你的控制器层中的方法,然后再回到浏览器/客户端。

DispatcherServlet具有很长的继承层次结构; 值得从上到下一一了解这些方面。 请求处理方法将使我们最感兴趣。

在标准开发过程中的本地以及远程了解HTTP请求是了解MVC体系结构的关键部分。

6、通用Servlet

GenericServlet是Servlet规范的一部分,不直接针对HTTP。 它定义了service()方法来接收传入的请求并产生响应。

请注意ServletRequest和ServletResponse方法参数如何不与HTTP协议绑定:

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

这是最终对服务器的任何请求(包括简单的GET请求)调用的方法。

7、HttpServlet

顾名思义,HttpServlet类是以HTTP为中心的Servlet实现,也由规范定义。

用更实际的术语来说,HttpServlet是带有service()方法实现的抽象类,该实现按HTTP方法类型拆分请求,并且大致如下所示:

protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
    String method = req.getMethod();
    if (method.equals(METHOD_GET)) {
        // ...
        doGet(req, resp);
    } else if (method.equals(METHOD_HEAD)) {
        // ...
        doHead(req, resp);
    } else if (method.equals(METHOD_POST)) {
        doPost(req, resp);
        // ...
    }

8、HttpServletBean

接下来,HttpServletBean是层次结构中第一个支持Spring的类。 它使用从web.xml或WebApplicationInitializer接收到的servletinit-param值注入bean的属性。

如果是对你的应用程序的请求,则针对那些特定的HTTP请求调用doGet(),doPost()等方法。.

9、FrameworkServlet

FrameworkServlet将Servlet功能与Web应用程序上下文集成在一起,实现了ApplicationContextAware接口。 但是它也能够自行创建Web应用程序上下文。

如你所见,HttpServletBean超类将init-params注入为bean属性。 因此,如果在servlet的contextClassinit参数中提供了上下文类名称,则将创建此类的实例作为应用程序上下文。 否则,将使用默认的XmlWebApplicationContext类。

由于当今XML配置已经过时,因此Spring Boot默认使用AnnotationConfigWebApplicationContext配置DispatcherServlet。 但是你可以轻松更改它。

例如,如果你需要使用基于Groovy的应用程序上下文来配置Spring Web MVC应用程序,则可以在web.xml文件中使用DispatcherServlet的以下配置:

 dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        contextClass
        org.springframework.web.context.support.GroovyWebApplicationContext

可以使用WebApplicationInitializer类以更现代的基于Java的方式完成相同的配置。

先写到这里,晚点再更新第二个章节

第二更来了,下方链接可直达。
摸透Spring MVC真正如何工作核心原理(part:2)

如果这个文章写得还不错,觉得有点东西的话 求点赞 求关注❤️ 求分享,感谢大家的支持和认可。

还有就是这我总结出了一些架构视频资料和互联网公司java程序员面试涉及到的绝大部分面试题和答案做成了文档和架构视频资料还有完整高清的java进阶架构学习路线图free分享给大家(包括Dubbo、Redis、Netty、zookeeper、Springcloud、分布式、高并发等架构技术资料),可以加vx:ddmsiqi领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值