Spring Boot系列(一) Spring Boot准备知识
本文是学习 Spring Boot 的一些准备知识.
Spring Web MVC
Spring Web MVC 的两个Context
如下图所示, 基于 Servlet 的 Spring Web MVC 启动时会创建两个上下文, 即 Servlet WebApplicationContext 和 Root WebApplicationContext.
前者是 DispatcherServlet引导创建的, 后者由 ServletContextListener 创建, 包含服务,数据库操作等非 Web 相关的组件.

DispatcherServlet
DispatcherServlet 是前端控制器, Spring MVC 遵循前端控制器模式(具体参看<Java EE 核心模式>一书). 前端控制器是 MVC 模式中 C 的一部分, 除此之外, C 还包括我们定义的 Controller 等应用控制器类.
HandlerMapping
- 传统 Servlet 的请求 url 模式
Servlet规范中描述了 Servlet 和 Filter 的 URL 匹配模式. 如下;
- 精确匹配, 如
/index - 扩展名匹配, 如
*.jsp - 路径匹配, 如
/hive/
优先级按精确匹配 > 最长路径匹配 > 扩展名匹配.
- Spring MVC 中的
HandlerMapping
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 = "/";
}
HandlerMapping
用来找到 URL 匹配的 Handler 方法, 这些方法正是我们定义的 Controller 中的方法. 这些方法被 @RequestMapping 标记. 这个注解还有一些变体(CRUD): GetMapping , PostMapping, PutMapping, DeleteMapping等.
可以使用实现接口
HandlerInterceptor拦截器来验证 handler 的本质. 其中一个方法的签名是boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler). 注意handler定义的类型是Object, 说明handler的类型可能不止是HandlerMethod.
异常处理
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准备知识的更多相关文章
- Spring框架系列(2) - Spring简单例子引入Spring要点
上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...
- Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计
在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...
- Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现
我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...
- Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程
上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...
- Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)
上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...
- Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现
前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...
- Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建
上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...
- Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现
上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...
- 【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 ...
随机推荐
- admin-handlers.go
package],,) ],,) ],,) ],,) ],,) ]) if err == redis.Nil { http.NotFound(w, r) } else ...
- Golang 通用连接池库 Golang-Pool
Golang 实现的连接池 功能: * 连接池中连接类型为interface{},使得更加通用 * 链接的最大空闲时间,超时的链接将关闭丢弃,可避免空闲时链接自动失效问题 * 使用channel处理池 ...
- 【codeforces 698B】 Fix a Tree
题目链接: http://codeforces.com/problemset/problem/698/B 题解: 还是比较简单的.因为每个节点只有一个父亲,可以直接建反图,保证出现的环中只有一条路径. ...
- 【构造】Bzoj1432[ZJOI2009]Function
Description Input 一行两个整数n; k. Output 一行一个整数,表示n 个函数第k 层最少能由多少段组成. Sample Input 1 1 Sample Output 1 ...
- BZOJ_1552_[Cerc2007]robotic sort_splay
BZOJ_1552_[Cerc2007]robotic sort_splay 题意: 分析: splay维护区间操作 可以先把编号排序,给每个编号分配一个固定的点,映射过去 查找编号的排名时先找到这个 ...
- BZOJ1854: [Scoi2010]游戏 二分图
很早之前写的题了,发现没有更博,想了想,更一发出来. Orz ljss 这是冬令营上的例题...之后,我推出来了一种时间复杂度没有问题,空间复杂度没有问题的方法,额(⊙o⊙)…和给出的正解不同,但是能 ...
- 流程控制之for循环
目录 语法(掌握) for+break for+continue for循环嵌套(掌握) for+else(掌握) for循环实现loading(了解) 语法(掌握) 为什么有了while循环,还需要 ...
- SQLI LABS Challenges Part(54-65) WriteUp
终于到了最后一部分,这些关跟之前不同的是这里是限制次数的. less-54: 这题比较好玩,10次之内爆出数据.先试试是什么类型: ?id=1' and '1 ==>>正常 ?id=1' ...
- 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制
背景: GDI+ 绘制文本 时,如果 背景是透明的 —— 则会出现 锯齿. //其实,我不用这三个 属性 好多年了 //而且,这三个属性 在关键时刻还有可能 帮倒忙 //关键是:这三个属性,鸟用都没有 ...
- 结合JDK源码看设计模式——迭代器模式
前言: Iterator翻译过来就是迭代器的意思.在前面的工厂模式中就介绍过了iterator,不过当时介绍的是方法,现在从Iterator接口的设计来看,似乎又是一种设计模式,下面我们就来讲讲迭代器 ...