共计 8548 个字符,预计需要花费 22 分钟才能阅读完成。
引言
当初各大技术社区 Spring Boot 的文章越来越多,Spring Boot 相干的图文、视频教程越来越多,应用 Spring Boot 的互联网公司也越来越多;Java 程序员当初进来面试,Spring Boot 曾经成了必问的内容。
一切都在证实,Spring Boot 曾经成为了 Java 程序员必备的技能。并且能够预感的是将来 Spring Boot 的倒退还会更好。
所以对 Java 程序员来说其中不乏说对 Spring Boot 十分相熟的,而后当问到一些 Spring Boot 外围性能和原理的时候,没人能说得上来,或者说不到点上,能够说一个问题就问趴下了!(问题:你能讲下为什么咱们要用 Spring Boot 吗?)
置信我,下面这些相似的问题,90% 有教训的 Java 程序员超都曾遇见过!但很少有系统化的答复。
因而,总结了这份 Spring Boot 外围知识点实战教程,通过这份教程,带你梳理 Spring Boot 技术体系。
文末有彩蛋~
Spring Boot2 教程
在 Spring Boot 我的项目中,失常来说是不存在 XML 配置,这是因为 Spring Boot 不举荐应用 XML,留神,并非不反对,Spring Boot 举荐开发者应用 Java 配置来搭建框架,Spring Boot 中,大量的自动化配置都是通过 Java 配置来实现的,这一套实现计划,咱们也能够本人做,即本人也能够应用纯 Java 来搭建一个 SSM 环境,即在我的项目中,不存在任何 XML 配置,包含 web.xml。
环境要求:
应用纯 Java 来搭建 SSM 环境,要求 Tomcat 的版本必须在 7 以上。
1、创立工程
创立一个一般的 Maven 工程(留神,这里能够不用创立 Web 工程),并增加 SpringMVC 的依赖,同时,这里环境的搭建须要用到 Servlet,所以咱们还须要引入 Servlet 的依赖(肯定不能应用低版本的 Servlet),最终的 pom.xml 文件如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
2、增加 Spring 配置
工程创立胜利之后,首先增加 Spring 的配置文件,如下:
@Configuration
@ComponentScan(basePackages = "org.javaboy", useDefaultFilters = true,
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
Controller.class)})
public class SpringConfig {}
对于这个配置,我说如下几点:
@Configuration 注解示意这是一个配置类,在咱们这里,这个配置的作用相似于 applicationContext.xml
@ComponentScan 注解示意配置包扫描,里边的属性和 xml 配置中的属性都是一一对应的,useDefaultFilters 示意应用默认的过滤器,而后又除去 Controller 注解,即在 Spring 容器中扫描除了 Controller 之外的其余所有 Bean。
3、增加 SpringMVC 配置
接下来再来创立 springmvc 的配置文件:
@Configuration
@ComponentScan(basePackages = "org.javaboy",useDefaultFilters =
false,includeFilters = {@ComponentScan.Filter(type =
FilterType.ANNOTATION,classes = Controller.class)})
public class SpringMVCConfig {}
留神,如果不须要在 SpringMVC 中增加其余的额定配置,这样就能够了。即视图解析器、JSON 解析、文件上传 …… 等等,如果都不须要配置的话,这样就能够了。
4、配置 web.xml
此时,咱们并没 web.xml 文件,这时,咱们能够应用 Java 代码去代替 web.xml 文件,这里会用到 WebApplicationInitializer,具体定义如下:
public class WebInit implements WebApplicationInitializer {public void onStartup(ServletContext servletContext) throws ServletException
{
// 首先来加载 SpringMVC 的配置文件
AnnotationConfigWebApplicationContext ctx = new
AnnotationConfigWebApplicationContext();
ctx.register(SpringMVCConfig.class);
// 增加 DispatcherServlet
ServletRegistration.Dynamic springmvc =
servletContext.addServlet("springmvc", new DispatcherServlet(ctx));
// 给 DispatcherServlet 增加门路映射
springmvc.addMapping("/");
// 给 DispatcherServlet 增加启动机会
springmvc.setLoadOnStartup(1);
}
}
WebInit 的作用相似于 web.xml,这个类须要实现 WebApplicationInitializer 接口,并实现接口中的办法,当我的项目启动时,onStartup 办法会被主动执行,咱们能够在这个办法中做一些我的项目初始化操作,例如加载 SpringMVC 容器,增加过滤器,增加 Listener、增加 Servlet 等。
留神:
因为咱们在 WebInit 中只是增加了 SpringMVC 的配置,这样我的项目在启动时只会去加载 SpringMVC 容器,而不会去加载 Spring 容器,如果肯定要加载 Spring 容器,须要咱们批改 SpringMVC 的配置,在 SpringMVC 配置的包扫描中也去扫描 @Configuration 注解,进而加载 Spring 容器,还有一种计划能够解决这个问题,就是间接在我的项目中舍弃 Spring 配置,间接将所有配置放到 SpringMVC 的配置中来实现,这个在 SSM 整合时是没有问题的,在理论开发中,较多采纳第二种计划,第二种计划,SpringMVC 的配置如下:
@Configuration
@ComponentScan(basePackages = "org.javaboy")
public class SpringMVCConfig {}
这种计划中,所有的注解都在 SpringMVC 中扫描,采纳这种计划的话,则 Spring 的配置文件就能够删除了。
5、测试
最初,增加一个 HelloController,而后启动我的项目进行测试:
@RestController
public class HelloController {@GetMapping("/hello")
public String hello() {return "hello";}
}
启动我的项目,拜访接口,后果如下:
Spring Boot 全局异样解决
在 Spring Boot 我的项目中,异样对立解决,能够应用 Spring 中 @ControllerAdvice 来对立解决,也能够本人来定义异样解决计划。Spring Boot 中,对异样的解决有一些默认的策略,咱们别离来看。
默认状况下,Spring Boot 中的异样页面 是这样的:
咱们从这个异样提醒中,也能看进去,之所以用户看到这个页面,是因为开发者没有明确提供一个 /error 门路,如果开发者提供了 /error 门路,这个页面就不会展现进去,不过在 Spring Boot 中,提供 /error 门路实际上是下下策,Spring Boot 自身在解决异样时,也是当所有条件都不满足时,才会去找 /error 门路。那么咱们就先来看看,在 Spring Boot 中,如何自定义 error 页面,整体上来说,能够分为两种,一种是动态页面,另一种是动静页面。
动态异样页面
自定义动态异样页面,又分为两种,第一种 是应用 HTTP 响应码来命名页面,例如 404.html、405.html、500.html ….,另一种就是间接定义一个 4xx.html,示意 400-499 的状态都显示这个异样页面,5xx.html 示意 500-599 的状态显示这个异样页面。
默认是在 classpath:/static/error/ 门路下定义相干页面:
此时,启动我的项目,如果我的项目抛出 500 申请谬误,就会主动展现 500.html 这个页面,产生 404 就会展现 404.html 页面。如果异样展现页面既存在 5xx.html,也存在 500.html,此时,产生 500 异样时,优先展现 500.html 页面。
动静异样页面
动静的异样页面定义形式和动态的根本 统一,能够采纳的页面模板有 jsp、freemarker、thymeleaf。
动静异样页面,也反对 404.html 或者 4xx.html,然而一般来说,因为动静异样页面能够间接展现异样详细信息,所以就没有必要挨个枚举谬误了,间接定义 4xx.html(这里应用 thymeleaf 模板)或者 5xx.html 即可。
留神,动静页面模板,不须要开发者本人去定义控制器,间接定义异样页面即可,Spring Boot 中自带的异样处理器会主动查找到异样页面。
页面定义如下:
页面内容如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>5xx</h1>
<table border="1">
<tr>
<td>path</td>
<td th:text="${path}"></td>
</tr>
<tr>
<td>error</td>
<td th:text="${error}"></td>
</tr>
<tr>
<td>message</td>
<td th:text="${message}"></td>
</tr>
<tr>
<td>timestamp</td>
<td th:text="${timestamp}"></td>
</tr>
<tr>
<td>status</td>
<td th:text="${status}"></td>
</tr>
</table>
</body>
</html>
默认状况下,残缺的异样信息就是这 5 条,展现 成果如下:
如果动静页面和动态页面同时定义了异样解决页面,例如 classpath:/static/error/404.html 和 classpath:/templates/error/404.html 同时存在时,默认应用动静页面。即残缺的谬误页面查找
形式应该是这样:
产生了 500 谬误 –> 查找动静 500.html 页面 –> 查找动态 500.html –> 查找动静 5xx.html–> 查找动态 5xx.html。
自定义异样数据
默认状况下,在 Spring Boot 中,所有的异样数据其实就是上文所展现进去的 5 条数据,这 5 条数据定义在 org.springframework.boot.web.reactive.error.DefaultErrorAttributes 类中,具体定义在 getErrorAttributes 办法中:
public Map<String, Object> getErrorAttributes(ServerRequest request,
boolean includeStackTrace) {Map<String, Object> errorAttributes = new LinkedHashMap<>();
errorAttributes.put("timestamp", new Date());
errorAttributes.put("path", request.path());
Throwable error = getError(request);
HttpStatus errorStatus = determineHttpStatus(error);
errorAttributes.put("status", errorStatus.value());
errorAttributes.put("error", errorStatus.getReasonPhrase());
errorAttributes.put("message", determineMessage(error));
handleException(errorAttributes, determineException(error),
includeStackTrace);
return errorAttributes;
}
DefaultErrorAttributes 类自身则是在
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 异样主动配置类中定义的,如果开发者没有本人提供一个 ErrorAttributes 的实例的话,那么 Spring Boot 将主动提供一个 ErrorAttributes 的实例,也就是 DefaultErrorAttributes。
基于此,开发者自定义 ErrorAttributes 有两种形式:
- 间接实现 ErrorAttributes 接口
- 继承 DefaultErrorAttributes(举荐),因为 DefaultErrorAttributes 中对异样数据的解决曾经实现,开发者能够间接应用。
具体定义如下:
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean
includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest,
includeStackTrace);
if ((Integer)map.get("status") == 500) {map.put("message", "服务器外部谬误!");
}
return map;
}
}
定义好的 ErrorAttributes 肯定要注册成一个 Bean,这样,Spring Boot 就不会应用默认的 DefaultErrorAttributes 了,运行成果如下图:
自定义异样视图
异样视图默认就是后面所说的动态或者动静页面,这个也是能够自定义的,首先,默认的异样视图加载逻辑在 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController 类的 errorHtml 办法中,这个办法用来返回异样页面 + 数据,还有另外一个 error 办法,这个办法用来返回异样数据(如果是 ajax 申请,则该办法会被触发)。
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {HttpStatus status = getStatus(request);
Map<String, Object> model =
Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request,
MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status,
model);
return (modelAndView != null) ? modelAndView : new ModelAndView("error",
model);
}
在该办法中,首先会通过 getErrorAttributes 办法去获取异样数据(实际上会调用到 ErrorAttributes 的实例 的 getErrorAttributes 办法),而后调用 resolveErrorView 去创立一个 ModelAndView,如果这里创立失败,那么用户将会看到默认的谬误提醒页面。
失常状况下,resolveErrorView
办法会来到 DefaultErrorViewResolver
类的 resolveErrorView
办法中:
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status,
Map<String, Object> model) {ModelAndView modelAndView = resolve(String.valueOf(status.value()),
model);
if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {modelAndView = resolve(SERIES_VIEWS.get(status.series()),
model);
}
return modelAndView;
}
在这里,首先以异样响应码作为视图名别离去查找动静页面和动态页面,如果没有查找到,则再以 4xx 或者 5xx 作为视图名再去别离查找动静或者动态页面。
要自定义异样视图解析,也很容易,因为 DefaultErrorViewResolver 是在 ErrorMvcAutoConfiguration 类中提供的实例,即开发者没有提供相干实例时,会应用默认的 DefaultErrorViewResolver,开发者提供了本人的 ErrorViewResolver 实例后,默认的配置就会生效,因而,自定义异样视图,只须要提供 一个 ErrorViewResolver 的实例即可:
@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
public MyErrorViewResolver(ApplicationContext applicationContext,
ResourceProperties resourceProperties) {super(applicationContext, resourceProperties);
}
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status, Map<String, Object> model) {return new ModelAndView("/aaa/123", model);
}
}
实际上,开发者也能够在这里定义异样数据(间接在 resolveErrorView 办法从新定义一个 model,将参数中的 model 数据拷贝过来并批改,留神参数中的 model 类型为 UnmodifiableMap,即不能够间接批改),而不须要自定义 MyErrorAttributes。定义实现后,提供一个名为 123 的视图,如下图:
如此之后,谬误试图就算定义胜利了。
总结
实际上也能够自定义异样控制器 BasicErrorController,不过我感觉这样太大动干戈了,没必要,后面几种形式曾经能够满足咱们的大部分开发需要了。如果是前后端拆散架构,异样解决还有其余一些解决计划,这个当前和大家聊。
篇幅无限,其余内容就不在这里一一展现了,这份 Spring Boot 实战教程已整顿成一份 PDF 文档,共有 200 多页。
关注公众号:程序零世界,回复 666 获取这份整顿好的 Spring Boot 实战教程。
最初
欢送大家一起交换,喜爱文章记得点 ge 赞哟,感激反对!