文档章节

SpringMvc 框架阅读记录

lemos
 lemos
发布于 2016/11/18 09:50
字数 1061
阅读 4
收藏 0

简介

springmvc 是spring框架的一个模块,springmvc和spring 无需通过中间整合层进行整合。
springmvc是一个基于mvc的web框架。

MVC模式最早由Trygve Reenskaug在1978年提出[1],是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。MVC模式的目的是实现一种动态的程式设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。专业人员可以通过自身的专长分组:

  • 控制器(Controller)- 负责转发请求,对请求进行处理。
  • 视图(View) - 界面设计人员进行图形界面设计。
  • 模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

 

MVC 在B/S 系统下的应用

 

SpringMVC框架

官方文档

Spring Web MVC 是基于 Servlet API 设计的,它被部署到 Servlet 容器 中

 

DispatcherServlet (前端控制器)

WebApplicationContext 是根据自己的配置对普通的 ApplicationContext 进行扩展。

它有一个指向 ServletContext 容器和其相关联的 Servlet 的连接。

 

1> Web 系统读取 web.xml 文件

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

...


<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

 

2> ContextLoaderListener 寻找相应的 /WEB-INF/applicationContext*.xml 文件并加载

此时 Spring 创建一个 WebApplicationContext 对象,将其存储在 ServletContext 中。

注:可以通过下面的方法从 ServletContext 中获取当时的 WebApplicationContext。

WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

 

Spring 容器分级

由下图可以看出 , DispatcherServlet 需要 WebApplicationContext。Web  ApplicationContext 一般 需要分级成 两级容器:一级是 Root WebApplicationContext,另一级是 Servlet WebApplicationContext 。前者被多个 servlet 共享,后者则是根据自己应用的 servlet 配置而来。

由图还可以看出,Root WebApplicationContext 与 Servlet WebApplicationContext  不是包含关系,只是存在引用Servlet WebApplicationContext 引用 Root WebApplicationContext

 


注:不分级的话,只有一个 单独的 WebApplicationContext 也是足够的,则所有 beans 都要从 Root WebApplicationContext 中获取。

 

再结合具体代码去理解:

1)通过 web.xml 配置 ServletContext(Servlet 容器),包含 RootApplicationContext 根容器,前端控制器( Servlet WebApplicationContext 子容器)

<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value> // Root WebApplicationContext 根容器配置
    </context-param>

    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app1-context.xml</param-value> // Servlet WebApplicationContext 子容器配置
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
    </servlet-mapping>

</web-app>

2)引入了一个 前端控制器(包含一个 Servlet WebApplicationContext 子容器 )

import org.springframework.web.WebApplicationInitializer;

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}

3)引入了一个 前端控制器(包含一个 Servlet WebApplicationContext 子容器)

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

 

基本处理流程

上面的容器部署好了,下面开始 DispatcherServlet 处理请求:

用户发出请求 -> WebApplicationContext  绑定request 作为自己的一个属性,以便 Controller可以访问到。实际上也是绑定 request 到 Thread ->  locale resolver,theme resolver,multipart file resolver 依次绑定到 request ,让其决定使用哪个resolver -> 搜索合适的 handler 处理,执行链 preprocessors, postprocessors, and controllers,直接返回或填充 model -> 回收 model,渲染视图。

WebApplicationContext 上声明的 HandlerExceptionResolver 负责处理请求过程中的异常。

 

实际应用

HandlerMapping 可以实现 Interception 拦截器

  • preHandle(..) — before the actual handler is executed

  • postHandle(..) — after the handler is executed

  • afterCompletion(..) — after the complete request has finished

还支持 Filter(如 cors filter),这类 Filter 不包括在 servlet 中。注解 请看,RestTemplate 请看

 

参考资料

https://zh.wikipedia.org/wiki/MVC

https://spring.io/docs/reference

http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html

© 著作权归作者所有

共有 人打赏支持
lemos
粉丝 7
博文 182
码字总数 91912
作品 0
芜湖
后端工程师
私信 提问
Spring Social 1.0.1 发布

Spring Social 1.0.1 包含 Social Twitter 1.0.1 和 Spring Social Facebook 1.0.1 ,该版本主要是修复了 1.0 的一些小问题,完整改进记录请看 (Core | Facebook | Twitter) 下载地址:(Core...

红薯
2011/12/17
542
1
请教spring源码的阅读方法

oschina上不贬大牛,想请教一下,spring源码的阅读方法。 在没有考虑,一头栽进去的时候,发现,阅读起来有些困难。 我是先从ContextListener开始逐步阅读的。感觉,spring拥有众多接口,用i...

大东哥
2010/06/03
4.3K
6
Spring Data Commons 1.13.7 和 2.0.0 RC3 发布

Spring Data Commons 1.13.7 和 2.0.0 RC3 已发布,本次更新包含较多更改: 点此查看 Spring Data Commons 1.13.7 的变更记录 点此查看 Spring Data Commons 2.0.0 RC3 的变更记录 下载地址和...

淡漠悠然
2017/09/13
888
3
Spring源码剖析开篇:Spring概述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a724888/article/details/73033273 欢迎阅读完整的专栏博客内容:Spring源码解析 本文首发于我的个人公众号:...

你的猫大哥
2017/06/11
0
0
Spring Cloud构建微服务架构服务注册与发现

Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、...

明理萝
06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

logback.xml 配置

需要引入 logback-core-1.1.2.jar <?xml version="1.0" encoding="UTF-8"?><configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 --> ......

夜醒者
8分钟前
1
0
Java 11 已发布,String 还能这样玩!

在文章《Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码》中,我有介绍到 Java 11 的八个新特性,其中关于 String 加强部分,我觉得有点意思,这里单独再拉出来讲。 Java 11 增加...

Java技术栈
32分钟前
6
0
什么是以太坊DAO?(二)

Decentralized Autonomous Organization,简称DAO,以太坊中重要的概念。一般翻译为去中心化的自治组织。 在上一节中,我们为了展示什么是DAO创建了一个合约,就像一个采用邀请制的俱乐部,会...

geek12345
47分钟前
4
0
全屋WiFi彻底无死角 这才是终极解决方案

无线网络现在不仅在家庭中不可或缺,在酒店、医院、学校等场景中的需求也越来越多。尤其是这些场景中,房间多但也需要每个房间都能够完美覆盖WiFi,传统的吸顶式AP就无法很好的解决问题。 H3...

linux-tao
今天
6
0
Python日期字符串比较

需要用python的脚本来快速检测一个文件内的二个时间日期字符串的大小,其实实现很简单,首先一些基础的日期格式化知识如下 复制代码 %a星期的简写。如 星期三为Web %A星期的全写。如 星期三为...

dragon_tech
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部