Spring MVC调度流程

一、Spring MVC的由来

 在最早期WEB系统有前端到后端是:

请求+JSP+Java Bean + 数据库 的模式,这种JSP和Java Bean前后端耦合在一起会带来很多麻烦,这种模式下JSP身兼多职,既要负责视图层的数据展示,又要负责业务流程控制,结构较为混乱,也不是我们所希望的松耦合架构,如下:

后来被Servlet+JSP+Java Bean+数据库 的模式取代,多了一个Serverlet组件,用户的请求先到Servlet,Servlet相当于一个控制器,它来调度Java Bean以及读取数据库,最后把结果放到JSP进行展示。这时Servlet就是Controller,Java Bean就是Model,JSP就是View,这时前端和后端是解耦的,这时MVC分层架构的由来。当业务流程比较复杂的时候,就需要把业务流程控制交给专门的控制器,JSP只专注于视图的渲染展现即可。但是随着移动端手机、平板、各种终端的请求增加,这种模式的短板也暴露出来,那就是JSP适用于WEB端,但是不支持移动端。

为了兼顾各种终端,Spring MVC框架在上面的基础上进行了调整。它将原来的Model层又拆分成Service层和Dao层,如下:

Spring MVC是Spring家族中应用于Web应用的一个模块,是Spring提供的一个基于MVC设计模式的Web开发框架,可以将它理解为Servlet。在MVC模式中,Spring MVC作为控制器(Controller)来建立模型与视图的数据交互,是结构最清晰的JSP Model2实现,可以说是一个典型的MVC框架。

除此之外,Spring MVC框架采用松耦合、可插拔的组件结构,具有高度可配置性,比起其他的MVC框架更具有扩展性和灵活性。并且它本身就是Spring家族的一部分,与Spring框架整合更是天衣无缝。

在Spring MVC框架中,Controller替换Servlet来担负控制器的职责。Controller接收请求,调用相应的Model进行处理,Model处理完之后将结果返回给Controller,Conreoller再指派相应的View对处理结果进行渲染,最终响应给客户端进行展示。
 

SpringMVC 是基于 Spring 框架派生 Web 框架, 所以它天然就可以十分方便 整合 Spring 框架中,而 Spring 整合 Struts2 还是比较繁复的(另外Struts2 还爆出了漏洞问题)。

Spring MVC 开始就定位为松散的组合,展示给用户的视图(View)、 控制器返回的数据模型( Model )、 定位视图的视图解析器(ViewResolver) 和处理适配器( HandlerAdapter )等都是独立的,换句 话说, Spring MVC 很容易把后台数据转换为各种类型的数据 ,以满足互联网多样化的要求, 例如,Spring MVC 可以十分方便的转换为目前最常用 JSON 数据集,也可以转换为 PDF、Excel 和XML等。

下面我们需要研究下它的转换流程。

二、Spring MVC的组件与流程

流程和组件是 SpringMVC 的核心, Sp ringMVC 的流程是围 Dispatche rServlet 而工作的,所以  DispatcherServlet 是其最重要的 内容。在DispatcherServlet的基础上,还存在其他的组件, 掌握 流程和组件就是 SpringMVC 开发的 基础。总体流程图如下:

这个图不知道谁画的,画的还挺明白我就盗过来了,不过还是要解释一下:

图2-1
图2-2

首先,在Web务器启动的过程中,如果在 Spring Boot 机制下 Spring MVC 它就开始初始化一些重要的组件,例如 DispactherServlet,RequestMappingHandlerAdapter(HandlerAdapter的实现类)等组件对象。具体的可以查看spring webmvc-xxx.jar 包的属性文件DispatcherServlet.properties, 它定义的对象都是在 SpringMVC 开始时就初始化,并且存放在 Spring IoC容器中,如图2-1和图2-2。

 

我们先看一个Controller,也就是控制器:

@Controller
@RequestMapping("/home")
public class TestController {
    @RequestMapping("/test1")
    public String index_1(){
        String str = "666";
        ModelAndView mv = new ModelAndView();
        mv.setViewName("jj");
        mv.addObject("str", str);
        return str;
    }
}

@Controller注解标注这是一个控制器,@RequestMapping("/home")代表控制器和请求路径的映射关系,会在服务启动时就被扫描到HandlerMapping中存储,用户发起的请求会被DispactherServlet接收,并通过URI请求HandlerMapping返回一个HandlerExcutionChain对象,这个对象包含了处理器Handler,Handler是对控制器Controller的包装,同时Handler还包含拦截器(interceptor)。

DispactherServlet从HandlerMapping中得到了Handler,下面就需要执行这个Handler,执行Handler由HandlerAdapter完成。为什么还需要一个HandlerAdapter才能执行Handler?那是因为请求的种类的不同(有普通 HTTP 请求、WebSocket 的请求、按 BeanName 的请求),得到的Handler类型也不同,因此需要一个统一的适配器去运行HandlerExecutionChain 对象包含的Handler。

Handler在执行时会调用Controller,通过模型层获取数据,对数据进行处理后,最后返回模型和视图(ModelAndView )对象给DispactherServlet。(Controller方法可能存在参数,那么Handler就可以读入 HTTP和上下文的相关参数,然后再传递给Controller方法。而在Controller方法执行完成返回后,Handler又可以通过配置信息对控制器的返回结果进行处理

DispactherServlet拿到ModelAndView 对象就会转发给视图解析器( ViewResolver )。上面的代码中,我们给视图取名为“jj”,如果我们在配置文件中配置了视图的前缀和后缀:

spring.mvc.view.prefix=/WEB-INF/jsp
spring.mvc.view.suffix=.jsp

那么 ViewResolver 就会定位到视图, 就是/WEB-INF/jsp/jj .jsp 作为我们的视图。

视图解析器定位到视图后,视图的作用是将数据模型( Mode )渲染,这样就能够响应用户的请求。这一步就是视图将数据模型渲染( View )出来,用来展示给用户查看。

以上就是整个springMVC的调度流程。

猜你喜欢

转载自blog.csdn.net/weixin_41231928/article/details/106167398