互联网大厂必问的Spring boot已成为常态,现在学还来得及!

本文主要是介绍互联网大厂必问的Spring boot已成为常态,现在学还来得及!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

自 2014 年发布至今,Spring Boot 的搜索指数 一路飙升。没错 Spring Boot 越来越火了,作为一名行走一线的 Java 程序员,你可能在各个方面感受到了 Spring Boot 的火。

现在各大技术社区 Spring Boot 的文章越来越多,Spring Boot 相关的图文、视频教程越来越多,使用 Spring Boot 的互联网公司也越来越多; Java 程序员现在出去面试, Spring Boot 已经成了必问的内容。

一切都在证明,Spring Boot 已经成为了 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 文件如下:

 
  1. <dependency>

  2. <groupId>org.springframework</groupId>

  3. <artifactId>spring-webmvc</artifactId>

  4. <version>5.1.6.RELEASE</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>javax.servlet</groupId>

  8. <artifactId>javax.servlet-api</artifactId>

  9. <version>4.0.1</version>

  10. <scope>provided</scope>

  11. </dependency>

2 、添加 Spring 配置

工程创建成功之后,首先添加 Spring 的配置文件,如下:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy", useDefaultFilters = true,

  3. excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes =

  4. Controller.class)})

  5. public class SpringConfig {

  6. }

关于这个配置,我说如下几点:

@Configuration 注解表示这是一个配置类,在我们这里,这个配置的作用类似于applicationContext.xml

@ComponentScan 注解表示配置包扫描,里边的属性和 xml 配置中的属性都是一一对应的,useDefaultFilters 表示使用默认的过滤器,然后又除去 Controller 注解,即在 Spring 容器中扫描除了 Controller 之外的其他所有 Bean 。

3、 添加 SpringMVC 配置

接下来再来创建 springmvc 的配置文件:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy",useDefaultFilters =

  3. false,includeFilters = {@ComponentScan.Filter(type =

  4. FilterType.ANNOTATION,classes = Controller.class)})

  5. public class SpringMVCConfig {

  6. }

注意,如果不需要在SpringMVC中添加其他的额外配置,这样就可以了。即视图解析器、JSON解析、文件上传......等等,如果都不需要配置的话,这样就可以了。

4、配置 web.xml

此时,我们并没 web.xml 文件,这时,我们可以使用Java代码去代替 web.xml 文件,这里会用到WebApplicationInitializer ,具体定义如下:

 
  1. public class WebInit implements WebApplicationInitializer {

  2. public void onStartup(ServletContext servletContext) throws ServletException

  3. {

  4. //首先来加载 SpringMVC 的配置文件

  5. AnnotationConfigWebApplicationContext ctx = new

  6. AnnotationConfigWebApplicationContext();

  7. ctx.register(SpringMVCConfig.class);

  8. // 添加 DispatcherServlet

  9. ServletRegistration.Dynamic springmvc =

  10. servletContext.addServlet("springmvc", new DispatcherServlet(ctx));

  11. // 给 DispatcherServlet 添加路径映射

  12. springmvc.addMapping("/");

  13. // 给 DispatcherServlet 添加启动时机

  14. springmvc.setLoadOnStartup(1);

  15. }

  16. }

WebInit 的作用类似于 web.xml,这个类需要实现 WebApplicationInitializer 接口,并实现接口中的方法,当项目启动时,onStartup 方法会被自动执行,我们可以在这个方法中做一些项目初始化操作,例如加载 SpringMVC 容器,添加过滤器,添加 Listener、添加 Servlet 等。

注意:

由于我们在WebInit中只是添加了SpringMVC的配置,这样项目在启动时只会去加载SpringMVC容器,而不会去加载 Spring 容器,如果一定要加载 Spring 容器,需要我们修改 SpringMVC 的配置,在SpringMVC 配置的包扫描中也去扫描 @Configuration 注解,进而加载 Spring 容器,还有一种方案可以解决这个问题,就是直接在项目中舍弃 Spring 配置,直接将所有配置放到 SpringMVC 的配置中来完成,这个在 SSM 整合时是没有问题的,在实际开发中,较多采用第二种方案,第二种方案,SpringMVC 的配置如下:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy")

  3. public class SpringMVCConfig {

  4. }

这种方案中,所有的注解都在 SpringMVC 中扫描,采用这种方案的话,则 Spring 的配置文件就可以删除了。

5、测试

最后,添加一个 HelloController ,然后启动项目进行测试:

 
  1. @RestController

  2. public class HelloController {

  3. @GetMapping("/hello")

  4. public String hello() {

  5. return "hello";

  6. }

  7. }

启动项目,访问接口,结果如下:

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 中自带的异常处理器会自动查找到异常页面。

页面定义如下:

页面内容如下:

 
  1. <!DOCTYPE html>

  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">

  3. <head>

  4. <meta charset="UTF-8">

  5. <title>Title</title>

  6. </head>

  7. <body>

  8. <h1>5xx</h1>

  9. <table border="1">

  10. <tr>

  11. <td>path</td>

  12. <td th:text="${path}"></td>

  13. </tr>

  14. <tr>

  15. <td>error</td>

  16. <td th:text="${error}"></td>

  17. </tr>

  18. <tr>

  19. <td>message</td>

  20. <td th:text="${message}"></td>

  21. </tr>

  22. <tr>

  23. <td>timestamp</td>

  24. <td th:text="${timestamp}"></td>

  25. </tr>

  26. <tr>

  27. <td>status</td>

  28. <td th:text="${status}"></td>

  29. </tr>

  30. </table>

  31. </body>

  32. </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 方法中 :

 
  1. @Override

  2. public Map<String, Object> getErrorAttributes(ServerRequest request,

  3. boolean includeStackTrace) {

  4. Map<String, Object> errorAttributes = new LinkedHashMap<>();

  5. errorAttributes.put("timestamp", new Date());

  6. errorAttributes.put("path", request.path());

  7. Throwable error = getError(request);

  8. HttpStatus errorStatus = determineHttpStatus(error);

  9. errorAttributes.put("status", errorStatus.value());

  10. errorAttributes.put("error", errorStatus.getReasonPhrase());

  11. errorAttributes.put("message", determineMessage(error));

  12. handleException(errorAttributes, determineException(error),

  13. includeStackTrace);

  14. return errorAttributes;

  15. }

DefaultErrorAttributes 类本身则是在

org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 异常自动配置类中定义的,如果开发者没有自己提供一个 ErrorAttributes 的实例的话,那么 Spring Boot 将自动提供一个 ErrorAttributes 的实例,也就是 DefaultErrorAttributes 。

基于此 ,开发者自定义 ErrorAttributes 有两种方式 :

1. 直接实现 ErrorAttributes 接口

2. 继承 DefaultErrorAttributes(推荐),因为 DefaultErrorAttributes 中对异常数据的处理已经完成,开发者可以直接使用。

具体定义如下:

 
  1. @Component

  2. public class MyErrorAttributes extends DefaultErrorAttributes {

  3. @Override

  4. public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean

  5. includeStackTrace) {

  6. Map<String, Object> map = super.getErrorAttributes(webRequest,

  7. includeStackTrace);

  8. if ((Integer)map.get("status") == 500) {

  9. map.put("message", "服务器内部错误!");

  10. }

  11. return map;

  12. }

  13. }

定义好的 ErrorAttributes 一定要注册成一个 Bean ,这样,Spring Boot 就不会使用默认的DefaultErrorAttributes 了,运行效果如下图:

自定义异常视图

异常视图默认就是前面所说的静态或者动态页面,这个也是可以自定义的,首先 ,默认的异常视图加载逻辑在org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController 类的errorHtml 方法中,这个方法用来返回异常页面+数据,还有另外一个 error 方法,这个方法用来返回异常数据(如果是 ajax 请求,则该方法会被触发)。

 
  1. @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)

  2. public ModelAndView errorHtml(HttpServletRequest request,

  3. HttpServletResponse response) {

  4. HttpStatus status = getStatus(request);

  5. Map<String, Object> model =

  6. Collections.unmodifiableMap(getErrorAttributes(

  7. request, isIncludeStackTrace(request,

  8. MediaType.TEXT_HTML)));

  9. response.setStatus(status.value());

  10. ModelAndView modelAndView = resolveErrorView(request, response, status,

  11. model);

  12. return (modelAndView != null) ? modelAndView : new ModelAndView("error",

  13. model);

  14. }

在该方法中 ,首先会通过 getErrorAttributes 方法去获取异常数据(实际上会调用到 ErrorAttributes的实例 的 getErrorAttributes 方法),然后调用 resolveErrorView 去创建一个 ModelAndView ,如果这里创建失败,那么用户将会看到默认的错误提示页面。

正常情况下, resolveErrorView 方法会来到 DefaultErrorViewResolver 类的 resolveErrorView 方法中:

 
  1. @Override

  2. public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus

  3. status,

  4. Map<String, Object> model) {

  5. ModelAndView modelAndView = resolve(String.valueOf(status.value()),

  6. model);

  7. if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {

  8. modelAndView = resolve(SERIES_VIEWS.get(status.series()),

  9. model);

  10. }

  11. return modelAndView;

  12. }

在这里,首先以异常响应码作为视图名分别去查找动态页面和静态页面,如果没有查找到,则再以 4xx或者 5xx 作为视图名再去分别查找动态或者静态页面。

要自定义异常视图解析,也很容易 ,由于 DefaultErrorViewResolver 是在ErrorMvcAutoConfiguration 类中提供的实例,即开发者没有提供相关实例时,会使用默认的DefaultErrorViewResolver ,开发者提供了自己的 ErrorViewResolver 实例后,默认的配置就会失效,因此,自定义异常视图,只需要提供 一个 ErrorViewResolver 的实例即可:

 
  1. @Component

  2. public class MyErrorViewResolver extends DefaultErrorViewResolver {

  3. public MyErrorViewResolver(ApplicationContext applicationContext,

  4. ResourceProperties resourceProperties) {

  5. super(applicationContext, resourceProperties);

  6. }

  7. @Override

  8. public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus

  9. status, Map<String, Object> model) {

  10. return new ModelAndView("/aaa/123", model);

  11. }

  12. }

实际上,开发者也可以在这里定义异常数据(直接在 resolveErrorView 方法重新定义一个 model ,将参数中的model 数据拷贝过去并修改,注意参数中的 model 类型为 UnmodifiableMap,即不可以直接修改),而不需要自定义 MyErrorAttributes。定义完成后,提供一个名为 123 的视图,如下图:

如此之后,错误试图就算定义成功了。

总结

实际上也可以自定义异常控制器 BasicErrorController ,不过觉得这样太大动干戈了,没必要,前面几种方式已经可以满足我们的大部分开发需求了。如果是前后端分离架构,异常处理还有其他一些处理方案,这个以后和大家聊。

篇幅有限,其他内容就不在这里一一展示了,这份Spring Boot实战教程已整理成一份PDF文档,共有200多页。

关注公众号:麒麟改bug。

最后

欢迎大家一起交流,喜欢文章记得关注我点赞哟,感谢支持!

这篇关于互联网大厂必问的Spring boot已成为常态,现在学还来得及!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653174

相关文章

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp