互联网大厂必问的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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定