SpringBoot2核心技术-基础入门--day05

1. 错误处理

1.1 默认错误处理规则

SpringBoot中提供了错误页的默认处理规则,提供/error的路径处理所有错误的映射,对机器客户端,将错误信息以Json形式的数据返回。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
SpringBoot2核心技术-基础入门--day05
SpringBoot2核心技术-基础入门--day05

在默认路径下添加error文件夹,将4xx,5xx页面放进去会被自动解析

SpringBoot2核心技术-基础入门--day05

2、定制错误处理逻辑

error/404.html error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页
• @ControllerAdvice+@ExceptionHandler处理全局异常;底层是 ExceptionHandlerExceptionResolver 支持的
• @ResponseStatus+自定义异常 ;底层是 ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
• Spring底层的异常,如 参数类型转换异常;DefaultHandlerExceptionResolver 处理框架底层的异常。
• response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());

• 自定义实现 HandlerExceptionResolver 处理异常;可以作为默认的全局异常处理规则

• ErrorViewResolver 实现自定义处理异常;
• response.sendError 。error请求就会转给controller
• 你的异常没有任何人能处理。tomcat底层 response.sendError。error请求就会转给controller
• basicErrorController 要去的页面地址是 ErrorViewResolver ;

3、异常处理自动配置原理

• ErrorMvcAutoConfiguration 自动配置异常处理规则
• 容器中的组件:类型:DefaultErrorAttributes -> id:errorAttributes
• public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver
• DefaultErrorAttributes:定义错误页面中可以包含哪些数据。


• 容器中的组件:类型:BasicErrorController --> id:basicErrorController(json+白页 适配响应)
• 处理默认 /error 路径的请求;页面响应 new ModelAndView("error", model);
• 容器中有组件 View->id是error;(响应默认错误页)
• 容器中放组件 BeanNameViewResolver(视图解析器);按照返回的视图名作为组件的id去容器中找View对象。
• 容器中的组件:类型:DefaultErrorViewResolver -> id:conventionErrorViewResolver
• 如果发生错误,会以HTTP的状态码 作为视图页地址(viewName),找到真正的页面
• error/404、5xx.html
如果想要返回页面;就会找error视图【StaticView】。(默认是一个白页)
写出去json
错误页

4、异常处理步骤流程

(1)、执行目标方法,目标方法运行期间有任何异常都会被catch、而且标志当前请求结束;并且用 dispatchException

(2)、进入视图解析流程(页面渲染?)

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

(3)、mv = processHandlerException;处理handler发生的异常,处理完成返回ModelAndView;

1、遍历所有的 handlerExceptionResolvers,看谁能处理当前异常【HandlerExceptionResolver处理器异常解析器】

2、系统默认的 异常解析器;

a、DefaultErrorAttributes先来处理异常。把异常信息保存到rrequest域,并且返回null;
b、默认没有任何人能处理异常,所以异常会被抛出

• 1、如果没有任何人能处理最终底层就会发送 /error 请求。会被底层的BasicErrorController处理
• 2、解析错误视图;遍历所有的 ErrorViewResolver 看谁能解析。
• 3、默认的 DefaultErrorViewResolver ,作用是把响应状态码作为错误页的地址,error/500.html

(4)、模板引擎最终响应这个页面 error/500.html

2、Web原生组件注入(Servlet、Filter、Listener)

2.1、使用Servlet API

@ServletComponentScan(basePackages = "com.atguigu.admin") :指定原生Servlet组件都放在那里
@WebServlet(urlPatterns = "/my"):效果:直接响应,没有经过Spring的拦截器?
@WebFilter(urlPatterns={"/css/*","/images/*"})
@WebListener

推荐可以这种方式;
扩展:DispatchServlet 如何注册进来
• 容器中自动配置了 DispatcherServlet 属性绑定到 WebMvcProperties;对应的配置文件配置项是 spring.mvc。
• 通过 ServletRegistrationBean 把 DispatcherServlet 配置进来。
• 默认映射的是 / 路径。
Tomcat-Servlet;
多个Servlet都能处理到同一层路径,精确优选原则
A: /my/
B: /my/1

2.2、使用RegistrationBean

ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean
@Configuration
public class MyRegistConfig {
    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my","/my02");
    }
    @Bean
    public FilterRegistrationBean myFilter(){
        MyFilter myFilter = new MyFilter();
//        return new FilterRegistrationBean(myFilter,myServlet());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }
    @Bean
    public ServletListenerRegistrationBean myListener(){
        MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
        return new ServletListenerRegistrationBean(mySwervletContextListener);
    }
}

3、嵌入式Servlet容器

3.1、切换嵌入式Servlet容器

• 默认支持的webServer
• Tomcat, Jetty, or Undertow
• ServletWebServerApplicationContext 容器启动寻找ServletWebServerFactory 并引导创建服务器
• 切换服务器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

• 原理
• SpringBoot应用启动发现当前是Web应用。web场景包-导入tomcat
• web应用会创建一个web版的ioc容器 ServletWebServerApplicationContext
• ServletWebServerApplicationContext 启动的时候寻找 ServletWebServerFactory(Servlet 的web服务器工厂---> Servlet 的web服务器)
• SpringBoot底层默认有很多的WebServer工厂;TomcatServletWebServerFactory, JettyServletWebServerFactory, or UndertowServletWebServerFactory
• 底层直接会有一个自动配置类。ServletWebServerFactoryAutoConfiguration
• ServletWebServerFactoryAutoConfiguration导入了ServletWebServerFactoryConfiguration(配置类)
• ServletWebServerFactoryConfiguration 配置类 根据动态判断系统中到底导入了那个Web服务器的包。(默认是web-starter导入tomcat包),容器中就有 TomcatServletWebServerFactory
• TomcatServletWebServerFactory 创建出Tomcat服务器并启动;TomcatWebServer 的构造器拥有初始化方法initialize---this.tomcat.start();
• 内嵌服务器,就是手动把启动服务器的代码调用(tomcat核心jar包存在)

3.2、定制Servlet容器

• 实现 WebServerFactoryCustomizer
• 把配置文件的值和ServletWebServerFactory 进行绑定
• 修改配置文件 server.xxx
• 直接自定义 ConfigurableServletWebServerFactory
xxxxxCustomizer:定制化器,可以改变xxxx的默认规则

import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }
}

4、定制化原理

4.1、定制化的常见方式

• 修改配置文件;
• xxxxxCustomizer;
• 编写自定义的配置类 xxxConfiguration;+ @Bean替换、增加容器中默认组件;视图解析器
• Web应用 编写一个配置类实现 WebMvcConfigurer 即可定制化web功能;+ @Bean给容器中再扩展一些组件

@Configuration
public class AdminWebConfig implements WebMvcConfigurer
• @EnableWebMvc + WebMvcConfigurer —— @Bean  可以全面接管SpringMVC,所有规则全部自己重新配置; 实现定制和扩展功能

• 原理
• 1、WebMvcAutoConfiguration 默认的SpringMVC的自动配置功能类。静态资源、欢迎页.....
• 2、一旦使用 @EnableWebMvc 、。会 @Import(DelegatingWebMvcConfiguration.class)
• 3、DelegatingWebMvcConfiguration 的 作用,只保证SpringMVC最基本的使用
• 把所有系统中的 WebMvcConfigurer 拿过来。所有功能的定制都是这些 WebMvcConfigurer 合起来一起生效
• 自动配置了一些非常底层的组件。RequestMappingHandlerMapping、这些组件依赖的组件都是从容器中获取
• public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
• 4、WebMvcAutoConfiguration 里面的配置要能生效 必须 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
• 5、@EnableWebMvc 导致了 WebMvcAutoConfiguration 没有生效。
• ... ...

4.2、原理分析套路

场景starter - xxxxAutoConfiguration - 导入xxx组件 - 绑定xxxProperties -- 绑定配置文件项

上一篇:SpringBoot2.X整合Redis


下一篇:玩转springboot2.x之异步调用@Async