本文是学习 Spring Boot 的一些准备知识.

Spring Web MVC

Spring Web MVC 的两个Context

如下图所示, 基于 Servlet 的 Spring Web MVC 启动时会创建两个上下文, 即 Servlet WebApplicationContextRoot WebApplicationContext.

前者是 DispatcherServlet引导创建的, 后者由 ServletContextListener 创建, 包含服务,数据库操作等非 Web 相关的组件.

DispatcherServlet

DispatcherServlet 是前端控制器, Spring MVC 遵循前端控制器模式(具体参看<Java EE 核心模式>一书). 前端控制器是 MVC 模式中 C 的一部分, 除此之外, C 还包括我们定义的 Controller 等应用控制器类.

HandlerMapping

  • 传统 Servlet 的请求 url 模式

Servlet规范中描述了 Servlet 和 Filter 的 URL 匹配模式. 如下;

  1. 精确匹配, 如 /index
  2. 扩展名匹配, 如 *.jsp
  3. 路径匹配, 如 /hive/

优先级按精确匹配 > 最长路径匹配 > 扩展名匹配.

  • Spring MVC 中的 HandlerMapping
  1. DispatcherServlet

Spring boot 中使用自动装配来实例化和启动 DispatcherServlet. 类名为 DispatcherServletAutoConfiguration, 路径默认为 "" 或 "/" . 可以修改配置, 对应的配置类为 WebMvcProperties , 对应的配置为 spring.mvc.servlet.path=/

从中可以看到 Spring 配置的一般规律, 其他的配置项也可以从配置类中找到依据.

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
...
@Configuration
@Conditional(DefaultDispatcherServletCondition.class)
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties({ HttpProperties.class, WebMvcProperties.class })
protected static class DispatcherServletConfiguration {
}
}
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
...
private final Servlet servlet = new Servlet();
...
}
public static class Servlet {

		/**
* Path of the dispatcher servlet.
*/
private String path = "/";
}
  1. HandlerMapping

用来找到 URL 匹配的 Handler 方法, 这些方法正是我们定义的 Controller 中的方法. 这些方法被 @RequestMapping 标记. 这个注解还有一些变体(CRUD): GetMapping , PostMapping, PutMapping, DeleteMapping等.

可以使用实现接口 HandlerInterceptor 拦截器来验证 handler 的本质. 其中一个方法的签名是 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler). 注意 handler 定义的类型是 Object, 说明handler的类型可能不止是 HandlerMethod .

异常处理

参看Spring系列(七) Spring MVC 异常处理

Servlet 规范

规范中定义了异常处理相关的返回信息应该包含什么内容. 如: javax.servlet.error.stauts_code 定义了错误码; javax.servlet.error.message 定义了错误信息; javax.servlet.error.exception 定义了异常.

Servlet 实现

web.xml 的配置如下:

<servlet>
<servlet-name>PageNotFoundServlet</servlet-name>
<servlet-class>com.xlx.servlet.PageNotFoundServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>PageNotFoundServlet</servlet-name>
<url-pattern>/404.html</url-pattern>
</servlet-mapping> <error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>

PageNotFoundServlet 实现:

public class PageNotFoundServlet extends HttpServlet{

    public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,Exception{

        // 此处验证request中设置的错误码.
request.getAttribute("javax.servlet.error.stauts_code"); response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.println("page not found...");
}
}

MVC 实现

通过 RestControllerAdvicer.

@RestConstrollerAdvice
public class RestControllerAdvicer{ @ExceptionHandler(NohandlerFoundException.class)
public Object pageNotFound(HttpStatus status,HttpServletRequest request,Throwable throwable){
Map<String,Object> errors = new HashMap<>();
errors.put("stauts_code",request.getAttribute("javax.servlet.error.stauts_code"));
errors.put("stauts_uri",request.getAttribute("javax.servlet.error.request_uri")); return error;
}
}

Spring Boot 实现

通过实现 ErrorPageRegistrar 注册错误页面.

public class Application implements ErrorPageRegistrar{

    @Override
public void registerErrorPages(ErrorPageRegistry registry){
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,"404.html"));
}
} .... @GetMapping("/404.html")
public Object handle404(){
// 实现错误处理
}

更多参看相关的那篇文章.

视图

View

接口 View 定义了一个 void render(@Nullable Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception; 方法, 用来渲染视图.

ViewReslover

接口 ViewReslover 定义解析视图名称的方法 @Nullable View resolveViewName(String var1, Locale var2) throws Exception; 用来寻找对应的view对象名称.

view 名称: prefix + viewname + suffix

前缀 prefix 和 后缀 suffix 同样可以配置

spring.mvc.view.suffix=.jsp

Thymeleaf

ThymeleafAutoConfiguration 同样可以找到对应的配置类 ThymeleafProperties.

  • ContentNegotiationViewResolver 内容协调处理器, 处理多个 viewResolver 的情况.

国际化(i18n)

  • 理解 MessageSource 抽象.

Spring Boot系列(一) Spring Boot准备知识的更多相关文章

  1. Spring框架系列(2) - Spring简单例子引入Spring要点

    上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...

  2. Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计

    在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...

  3. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  4. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  5. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  6. Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现

    前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...

  7. Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建

    上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...

  8. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

  9. 【Spring Boot && Spring Cloud系列】Spring Boot的启动器Starter

    Spring Boot的内置Servlet Container: Name Servlet Version Java Version Tomcat8 3.1 Java 7+ Tomcat7 3.0 J ...

随机推荐

  1. MYSQL—— 启动MYSQL 57 报错“The service MYSQL57 failed the most recent........等”的问题解决方式!

    每天开机之后,启动MYSQL Notifier就报错,第一次出现重启电脑后解决,后面的几天老是出现,重启电脑好几次都没有解决,感觉很烦人,一定要搞定这个问题找到原因,于是有了下文....... 启动M ...

  2. JAVAEE——SpringMVC第一天:介绍、入门程序、架构讲解、SpringMVC整合MyBatis、参数绑定、SpringMVC和Struts2的区别

    1. 学习计划   第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a) 框架结构 b) 组件说明 4.SpringMVC整合MyBatis 5.参数绑定 a) Sp ...

  3. 基于docker 如何部署surging分布式微服务引擎

    1.前言 转眼间surging 开源已经有1年了,经过1年的打磨,surging已从最初在window 部署的分布式微服务框架,到现在的可以在docker部署利用rancher 进行服务编排的分布式微 ...

  4. .net core Entity Framework 与 EF Core

    重点讲 Entity Framework Core ! (一)Entity Framework 它是适用于.NET 的对象关系映射程序 (ORM),现在的EF6已经是久经沙场,并经历重重磨难,获得一致 ...

  5. Docker 服务

    1.  Docker服务 作为一名后端攻城狮,对“服务”这个概念一定不陌生.比如,我们做一个会员系统,它可能会需要数据库.缓存.消息队列,这些都是中间件服务,除此以外可能还需要依赖其它的Dubbo服务 ...

  6. C语言memcpy函数的用法

    介绍 memcpy是memory copy的缩写,意为内存复制,在写C语言程序的时候,我们常常会用到它.它的函原型如下: void *memcpy(void *dest, const void *sr ...

  7. 网络协议 22 - RPC 协议(下)- 二进制类 RPC 协议

        前面我们认识了两个常用文本类的 RPC 协议,对于陌生人之间的沟通,用 NBA.CBA 这样的缩略语,会使得协议约定非常不方便.     在讲 CDN 和 DNS 的时候,我们讲过接入层的设计 ...

  8. 【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源

    如果你发现还有西半球的资源,烦请相告,不胜感谢! 一..NET Core基础 微软英文官网 .NET Core 微软中文官网 GitHub 用ASP.NET内核和Azure构建现代Web应用程序 博客 ...

  9. 安装Mysql时端口号3306被占用,解决方法

    当我们在卸载mysql数据库重新安装的时候,会出现端口号3306被占用的情况 有两种解决方案: 一:可以不使用3306端口,也可以换成别的端口,如3307,3308等等 二:可以打开命令窗口 1.wi ...

  10. 第10章 协议和声明类型常量 - IdentityModel 中文文档(v1.0.0)

    使用OAuth 2.0,OpenID Connect和声明时,声明类型和protocoal值有很多"魔术字符串".IdentityModel提供了几个常量字符串类来帮助它. 10. ...