SpringBoot的异常处理流程是什么样的?

一、默认异常处理机制

默认情况下,SpringBoot 提供 /error 请求,来处理所有异常的。

1.浏览器客户端,请求头里的属性是Accept:text/html。表明它想要一个html类型的文本数据。因此返回的错误视图以HTML格式呈现,也就是响应一个“ whitelabel”错误视图。

2.如果是其他客户端,请求头里的属性是Accept:/,默认响应一个json数据 。

二、异常处理流程

介绍异常处理流程前,要先认识HandlerExceptionResolver处理器异常解析器接口,可以将异常映射到相应的统一错误界面,从而显示用户友好的界面(而不是给用户看到具体的错误信息)

public interface HandlerExceptionResolver {
    //解析处理异常
	ModelAndView resolveException(
        HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);

}

DispatcherServlet初始化时,已经把所有的HandlerExceptionResolver处理器异常解析器接口的实现类放到下面的集合里了

public class DispatcherServlet extends FrameworkServlet {
    //异常解析器集合
	private List<HandlerExceptionResolver> handlerExceptionResolvers;
}

从上图可以看出该集合里有DefaultErrorAttributes;还有HandlerExceptionResolverComposite处理器异常解析器组合,这里面包含了三个能真正处理异常的解析器,分别是ExceptionHandlerExceptionResolverResponseStatusExceptionResolverDefaultHandlerExceptionResolver。下面会介绍他们几个分别用于处理什么异常。

阅读doDispatch()方法的源码可以看出,Spring MVC对整个doDispatch()方法用了嵌套的try-catch语句

  • 内层的try-catch用于捕获HandlerMapping进行映射查找HandlerExecutionChain以及HandlerAdapter执行具体Handler时的处理异常,并将异常传入到processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException)方法中。外层try-catch用于捕获渲染视图时的异常。
  • 通过两层嵌套的try-catch,SpringMVC就能够捕获到三大组件在处理用户请求时的异常,通过这样的方法能够很方便的实现统一的异常处理。
//处理分发结果
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
                                   HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

    //判断HandlerMapping、HandlerAdapter处理时的异常是否为空
    if (exception != null) {
        Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
        //异常不为空,处理异常,进行异常视图的获取
        mv = processHandlerException(request, response, handler, exception);
    }

    //只要存在mv就进行视图渲染
    if (mv != null && !mv.wasCleared()) {
        //不管视图是正常视图还是异常视图,均进入视图渲染流程
        render(mv, request, response);
        if (errorView) {
            WebUtils.clearErrorRequestAttributes(request);
        }
    }
 	...略
    ...略
   	...略
}

从上面代码可以看出,当出现异常时会进入processHandlerException()方法进行异常视图的获取,处理完成后返回是ModelAndView对象。接下来不管视图是正常视图还是异常视图,只要ModelAndView不为空,均进入视图渲染流程。下面是如何进行进行异常视图的获取的代码。

//处理异常,进行异常视图的获取
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
                                               Object handler, Exception ex) throws Exception {

    // Check registered HandlerExceptionResolvers...
    ModelAndView exMv = null;
    //遍历所有的处理器异常解析器handlerExceptionResolvers,看谁能够处理当前异常
    for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
        //解析当前异常
        exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);

        if (exMv != null) {
            //ModelAndView 不为空时,异常视图获取成功,跳出方法,进行异常视图渲染。
            break;
        }
    }

    ...略
    ...略
    ...略
   //所有处理器异常解析器都不能处理该异常,抛出异常
   throw ex;
}

遍历所有的处理器异常解析器handlerExceptionResolvers,看谁能够处理当前异常

  • DefaultErrorAttributes先来处理异常。把异常信息保存到request域,并且返回null,并不能真正解析。
  • HandlerExceptionResolverComposite会遍历它包含的三个异常解析器处理异常
  • ExceptionHandlerExceptionResolver处理器异常解析器支持@ControllerAdvice+@ExceptionHandler处理全局异常
  • ResponseStatusExceptionResolver处理器异常解析器支持@ResponseStatus+自定义异常
  • DefaultHandlerExceptionResolver 处理器异常解析器支持Spring底层的异常

当没有任何异常解析器能够处理异常,异常就会被抛出,最终Tomcat会发送 /error 请求,映射到底层的BasicErrorController进入默认的异常处理机制

总结:

当发生异常时,会被catch。遍历所有的处理器异常解析器,看谁能够解析。如果你使用了@ControllerAdvice+@ExceptionHandler配置了全局异常处理,并指定了错误视图,那么该异常会被处理,然后进入视图渲染流程。如果该异常没能够被任何处理器异常解析器处理,就会抛出异常,由Tomcat发送/error请求,进入默认的异常处理机制,也就是开头说的,没有配置错误状态码页面,则返回默认我们常见的默认错误页。

访问的是不存在的路径,此时不会发生异常,经过处理器映射,处理器适配调用仍然返回的是空的ModelAndView,所以无法进行视图渲染。Tomcat仍会发送 /error请求,进入默认的异常处理机制

三、默认的异常处理机制

要想弄懂错误处理原理,首先得看**ErrorMvcAutoConfiguration:这是错误处理的自动配置类**,给容器中添加了下面几个非常重要的组件。

  • ErrorPageCustomizer
  • BasicErrorController
  • DefaultErrorViewResolver
  • DefaultErrorAttributes

首先我们看ErrorPageCustomizer 组件,此组件是一个静态内部类,位于ErrorMvcAutoConfiguration内。它实现了ErrorPageRegistrar接口,该接口提供了可以用来注册ErrorPage的方法。官方将ErrorPage 描述为:简单的服务器独立的错误页面抽象,大致相当于web.xml中传统的元素<error-page>ErrorPage里包含了状态码、异常、和错误控制器映射路径(server.error.path=/error)。也就是说当发生了异常,而且所有的处理器异常解析器都处理不了该异常,Tomcat就会发送/error请求映射到BasicErrorController

static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
    //关于服务器的一些配置,如端口号,编码方式等。在这里主要关注server.error.path
    private final ServerProperties properties;

    private final DispatcherServletPath dispatcherServletPath;

    protected ErrorPageCustomizer(ServerProperties properties, DispatcherServletPath dispatcherServletPath) {
        this.properties = properties;
        this.dispatcherServletPath = dispatcherServletPath;
    }

    //注册错误页面
    @Override
    public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
        //ErrorPage里包含了状态码、异常、和错误控制器映射路径
        ErrorPage errorPage = new ErrorPage(
            //this.properties.getError().getPath()获取的就是server.error.path=/error(默认)
            this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));
        //注册ErrorPage
        errorPageRegistry.addErrorPages(errorPage);
    }
}
====================DispatcherServletPath接口=================================
public interface DispatcherServletPath {
    default String getRelativePath(String path) {
        String prefix = getPrefix();
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        return prefix + path;
    }
}

下面介绍的就是BasicErrorController。它里面有两个重要的方法,正好对象开头说的默认处理机制。方法一:如果是浏览器请求,则返回HTML响应数据text/html,方法二:如果是其他客户端请求,则返回JSON响应数据。

@Controller
//server.error.path 为空则用error.path, 再为空,再用/error
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

     //1、产生html类型的数据;浏览器客户端发送的请求来到这个方法处理
    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
	public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        //状态码
		HttpStatus status = getStatus(request);
        //从DefaultErrorAttributes里获取可以在页面显示的数据
		Map<String, Object> model = Collections
				.unmodifiableMap(getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
		response.setStatus(status.value());
        //调用父类里的方法,寻找错误视图解析器,来解析错误视图
		ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        //!!!如果没有配置具体的状态码错误页面或4xx,5xx这种视图,视图解析不成功,就会返回空的ModelAndView对象。此时就会构造一个默认的error错误视图,通过BeanNameViewResolver视图解析器,根据视图名(error)作为组件id去容器中找到View对象
		return (modelAndView != null) ? modelAndView : new ModelAndView("error", model);
	}

    //2、产生json数据,其他客户端来到这个方法处理
	@RequestMapping
	public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
		HttpStatus status = getStatus(request);
		if (status == HttpStatus.NO_CONTENT) {
			return new ResponseEntity<>(status);
		}
		Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
		return new ResponseEntity<>(body, status);
	}
}

========================AbstractErrorController================================
protected ModelAndView resolveErrorView(HttpServletRequest request,HttpServletResponse response, HttpStatus status, Map<String, Object> model) {

    for (ErrorViewResolver resolver : this.errorViewResolvers) {
        //错误视图解析器获取错误视图,返回ModelAndView
        ModelAndView modelAndView = resolver.resolveErrorView(request, status, model);
        if (modelAndView != null) {
            return modelAndView;
        }
    }
    return null;
}

总结一下,BasicErrorController主要作用:

处理默认/error 路径的请求

调用DefaultErrorViewResolver进行错误视图解析,分为三种情况

1.模板引擎支持解析,就去 /templates/error/下寻找我们配置的 状态码错误页面,例如404.html 或4xx.html。

2.模板引擎找不到这个错误页面,就去静态资源文件夹【/resources/、/static/、/public/、/META-INF/resources/】下的error文件夹下寻找状态码错误页面。

3.静态资源文件夹下也找不到,则new ModelAndView("error", model)构造一个默认的错误视图【就是经常见到的 Whitelabel Error Page】。该默认的错误视图在ErrorMvcAutoConfiguration里已经注册到容器里了,并且它在容器中的id就是error。后面就会通过BeanNameViewResolver视图解析器,根据视图逻辑 error,作为组件id去容器中就可以找到默认的错误视图。

=========================ErrorMvcAutoConfiguration========================================
protected static class WhitelabelErrorViewConfiguration {

		private final StaticView defaultErrorView = new StaticView();

    	//向容器种注册默认的错误视图,id为error
		@Bean(name = "error")
		@ConditionalOnMissingBean(name = "error")
		public View defaultErrorView() {
			return this.defaultErrorView;
		}
}
//可以看到静态内部类StaticView,进行视图渲染的时候,构造了我们经常看到的默认错误页面Whitelabel Error Page。
private static class StaticView implements View {

		@Override
		public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
				throws Exception {
			if (response.isCommitted()) {
				String message = getMessage(model);
				logger.error(message);
				return;
			}
			response.setContentType(TEXT_HTML_UTF8.toString());
			StringBuilder builder = new StringBuilder();
			Object timestamp = model.get("timestamp");
			Object message = model.get("message");
			Object trace = model.get("trace");
			if (response.getContentType() == null) {
				response.setContentType(getContentType());
			}
			builder.append("<html><body><h1>Whitelabel Error Page</h1>").append(
					"<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>")
					.append("<div id='created'>").append(timestamp).append("</div>")
					.append("<div>There was an unexpected error (type=").append(htmlEscape(model.get("error")))
					.append(", status=").append(htmlEscape(model.get("status"))).append(").</div>");
			if (message != null) {
				builder.append("<div>").append(htmlEscape(message)).append("</div>");
			}
			if (trace != null) {
				builder.append("<div style='white-space:pre-wrap;'>").append(htmlEscape(trace)).append("</div>");
			}
			builder.append("</body></html>");
			response.getWriter().append(builder.toString());
		}
}

接下来就是介绍 DefaultErrorViewResolver,主要就是进行错误视图解析。如果发生错误,就会以HTTP的状态码 作为视图地址,找到真正的错误页面。但是注意,首先是精确查找具体的错误状态码页面,然后是按照4xx,5xx这种查找

public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered {

    private static final Map<Series, String> SERIES_VIEWS;
    static {
        Map<Series, String> views = new EnumMap<>(Series.class);
        views.put(Series.CLIENT_ERROR, "4xx");
        views.put(Series.SERVER_ERROR, "5xx");
        SERIES_VIEWS = Collections.unmodifiableMap(views);
    }

    //解析错误视图,要去的错误页面
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        //先精确查找错误视图
        ModelAndView modelAndView = resolve(String.valueOf(status.value()), model);
        //精确查找不到,则查找4xx,5xx这种类型的错误页面
        if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
            modelAndView = resolve(SERIES_VIEWS.get(status.series()), model);
        }
        return modelAndView;
    }
    //真正解析 viewName是状态码
    private ModelAndView resolve(String viewName, Map<String, Object> model) {
     //!!!!默认SpringBoot可以去找到一个页面  error/404,注意定制错误页面要放在error文件夹下,如error/4xx.html
        String errorViewName = "error/" + viewName;

        //模板引擎可以解析这个页面地址就用模板引擎解析
        TemplateAvailabilityProvider provider = this.templateAvailabilityProviders
            .getProvider(errorViewName, this.applicationContext);
        if (provider != null) {
            //模板引擎可用的情况下返回到errorViewName指定的视图地址
            return new ModelAndView(errorViewName, model);
        }
        //模板引擎不可用,就在静态资源文件夹下找errorViewName对应的页面   error/404.html
        return resolveResource(errorViewName, model);
    }
    //模板引擎不可用,就去静态资源文件夹下寻找
    private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
        //这里遍历的是"classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/"
        for (String location : this.resourceProperties.getStaticLocations()) {
            try {
                Resource resource = this.applicationContext.getResource(location);
                resource = resource.createRelative(viewName + ".html");
                if (resource.exists()) {
                    return new ModelAndView(new HtmlResourceView(resource), model);
                }
            }
            catch (Exception ex) {
            }
        }
        return null;
    }
}

最后介绍DefaultErrorAttributes,里面存放了错误页面能够显示的数据。比如状态码、错误提示、异常消息等。

public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {
    //帮我们在页面共享信息
    @Override
        public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes,
                boolean includeStackTrace) {
            Map<String, Object> errorAttributes = new LinkedHashMap<String, Object>();
            errorAttributes.put("timestamp", new Date());
            addStatus(errorAttributes, requestAttributes);
            addErrorDetails(errorAttributes, requestAttributes, includeStackTrace);
            addPath(errorAttributes, requestAttributes);
            return errorAttributes;
        }
}

总结:

  • 当发生了异常,而且所有的处理器异常解析器都处理不了该异常ErrorPageCustomizer就会生效(定制错误的响应规则)。Tomcat就会发送/error请求,然后被HandlerMapping映射到BasicErrorController处理。
  • 解析错误视图:前提是配置了4xx.html、5xx.html错误状态码页面,去哪个状态码错误页面就由DefaultErrorViewResolver解析得到。如果没有配置错误状态码页面,就是默认的错误视图StaticView,它是位于ErrorMvcAutoConfiguration里的一个静态内部类,被自动注册到容器中。后面进行视图渲染的时候,就是StaticView里的render()方法构造了我们经常看到的默认错误页面【Whitelabel Error Page】。
  • 提取数据:页面能够获取什么数据是由 DefaultErrorViewResolver设置的。

四、自定义异常处理

1、自定义异常处理页

有模板引擎的情况下

  • 没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找。依然要将错误页面放在error文件夹下。
  • error/状态码.html,就是将错误页面命名为状态码.html放在模板引擎文件夹里面的 error文件夹下;我们可以使用4xx5xx作为错误页面的文件名来匹配这种类型的所有错误,不过优先寻找精确的状态码.html
  • 以上都没有找到错误页面,就是默认来到SpringBoot默认的错误提示页面。

错误页面能获取的信息DefaultErrorAttributes

  • timestamp:时间戳
  • status:状态码
  • error:错误提示
  • exception:异常对象
  • message:异常消息
  • errors:JSR303数据校验的错误都在这里

2、@ControllerAdvice+@ExceptionHandler处理全局异常

底层是由 ExceptionHandlerExceptionResolver处理器异常解析器支持的

3、@ResponseStatus+自定义异常

底层是由 ResponseStatusExceptionResolver处理器异常解析器支持的,但是它解析完成后,调用了 **response.sendError(statusCode, resolvedReason);**由tomcat发送的/error请求,进入默认异常处理机制

Spring底层的异常

如 参数类型转换异常;由DefaultHandlerExceptionResolver 处理器异常解析器支持的,处理框架底层的异常。但是它解析完成后,调用了 response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage()); 由tomcat发送的/error请求,进入默认处理机制。

扩展:【可不看】

自定义处理器异常解析器、错误视图解析器:

实现 HandlerExceptionResolver接口自定义处理器异常解析器;可以作为默认的全局异常处理规则

实现ErrorViewResolver自定义错误视图解析器

到此这篇关于SpringBoot的异常处理流程是什么样的?的文章就介绍到这了,更多相关SpringBoot异常处理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot处理全局统一异常的实现

    在后端发生异常或者是请求出错时,前端通常显示如下 Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Jun 07 15:38:07 CST 2019 There was an unexpected error (type=Not Found, status=404). No message available 对于

  • 详解SpringBoot 处理异常的几种常见姿势

    一.使用 @ControllerAdvice 和 @ExceptionHandler 处理全局异常 这是目前很常用的一种方式,非常推荐.测试代码中用到了 Junit 5,如果你新建项目验证下面的代码的话,记得添加上相关依赖. 1. 新建异常信息实体类 非必要的类,主要用于包装异常信息. src/main/java/com/twuc/webApp/exception/ErrorResponse.java /** * @author shuang.kou */ public class ErrorR

  • springboot异常处理的基本规范

    背景分析 在项目的开发中,不管是对底层的数据逻辑操作过程,还是业务逻辑的处理过程,还是控制逻辑的处理过程,都不可避免会遇到各种可预知的.不可预知的异常.处理好异常对系统有很好的保护作用,同时会大大提高用户的体验. 异常处理分析 概述 Java项目中处理异常方式无非两种,要么执行trycatch操作,要么执行throw操作(抛给其它对象处理),无论采用哪种方式,其目的是让我们的系统对异常要有反馈.但现在的问题是我们如何让这种反馈代码的编写即简单又直观.友好. 处理规范 我们在处理异常的过程中通常要

  • Springboot处理异常的常见方式

    一.制造异常 报500错误.在大量的代码中很难找到错误 二.统一异常处理 添加异常处理方法 GlobalExceptionHandler.java中添加 //指定出现什么异常执行这个方法 @ExceptionHandler(Exception.class) @ResponseBody //为了返回数据 public R error(Exception e) { e.printStackTrace(); return R.error().message("执行了全局异常处理.."); }

  • springboot拦截器过滤token,并返回结果及异常处理操作

    1.springboot 拦截器处理过滤token,并且返回结果 import org.apache.commons.lang3.StringUtils; import org.apache.shiro.subject.Subject; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.servlet.H

  • SpringBoot的异常处理流程是什么样的?

    一.默认异常处理机制 默认情况下,SpringBoot 提供 /error 请求,来处理所有异常的. 1.浏览器客户端,请求头里的属性是Accept:text/html.表明它想要一个html类型的文本数据.因此返回的错误视图以HTML格式呈现,也就是响应一个" whitelabel"错误视图. 2.如果是其他客户端,请求头里的属性是Accept:/,默认响应一个json数据 . 二.异常处理流程 介绍异常处理流程前,要先认识HandlerExceptionResolver:处理器异常

  • 详解SpringBoot异常处理流程及原理

    异常处理流程 执行目标方法,目标方法运行期间有任何异常都会被catch捕获,并标志当前请求结束,dispatchException抛出异常 进入视图解析流程,并渲染页面,发生异常时,参数mv为空,传入捕获的异常dispatchException 处理handler发生的异常,处理完成返回ModelAndView (1)遍历所有的HandlerExceptionResolvers,找到可以处理当前异常的解析器来解析异常 (2)调用resolveException解析异常,传入request和res

  • SpringBoot全局异常处理方案分享

    目录 一 业务场景 二 全局系统异常类 一)全局系统异常类 二) 包装异常返回结果给前端,修改自定义异常 三 返回案例 一 业务场景 调用接口时需要对属性进行校验,比如属性长度,当属性为邮箱时校验邮箱格式等,这时候要要用到@Validated注解,在使用这个注解后发现出现了一个问题,调用接口后并没有返回我们想要的报错结果,而是返回了 "message": "Validation failed for object='IMMessageSend'. Error count: 1

  • SpringBoot错误处理流程深入详解

    目录 一.错误处理 二.底层相关组件 三.异常处理流程 四.定制错误处理逻辑 1.自定义错误页面 2.使用注解或者默认的异常处理 3.自定义异常处理解析器 一.错误处理 默认情况下,Spring Boot提供/error处理所有错误的映射 对于机器客户端(例如PostMan),它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息(如果设置了拦截器,需要在请求头中塞入Cookie相关参数) 对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据

  • Java Controller实现参数验证与统一异常处理流程详细讲解

    目录 一,前期数据及类准备 1.1 统一状态码 1.2 统一返回格式 1.3 自定义接口API异常类 1.4 参数封装类 二,参数验证 2.1 pom.xml 2.2 修改参数封装类 2.3 controller 2.4 测试 三,统一异常处理 3.1 方法参数验证异常处理 3.2 其他异常处理 最近开发了比较多的接口,因为没有可参考的案例,所以一开始一直按照我的理解进行开发.开发多了发现自己每个结果都写了相同的代码:try() {} catch() {}, 和关于参数判空的:StringUti

  • SpringBoot 统一异常处理详解

    代码结构 配置pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/

  • springboot全局异常处理代码实例

    这篇文章主要介绍了springboot全局异常处理代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言: 开发中异常的处理必不可少,常用的就是 throw 和 try catch,这样一个项目到最后会出现很多冗余的代码,使用全局异常处理避免过多冗余代码. 全局异常处理: 1.pom 依赖(延续上一章代码): <dependencies> <!-- Spring Boot Web 依赖 --> <!-- Web 依赖

  • docker-compose镜像发布springboot项目的流程分析

    简介 Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排.Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project).Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理.因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理. Docker-Compose将所管理的

  • SpringBoot全局异常处理方式

    目录 SpringBoot全局异常处理 springboot全局异常处理--@ControllerAdvice+ExceptionHandler 一.全局捕获异常后,返回json给浏览器 二.全局捕获异常后,返回页面给浏览器 SpringBoot全局异常处理 为了让客户端能有一个更好的体验,当客户端发送请求到服务端发生错误时服务端应该明确告诉客户端错误信息. SpringBoot内置的异常处理返回的界面太杂乱,不够友好.我们需要将异常信息做封装处理响应给前端.本文介绍的为将错误信息统一封装成如下

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

随机推荐