记录一次统一异常处理类不生效的解决方案

前言

今天在使用@ControllerAdvice进行统一异常处理类时,没有起作用。先贴一下异常处理类的代码


package com.fxt.common.exception;
@Slf4j
//此处使用新的注解,相当于@ControllerAdvice和@@ResponseBody 结合体。
@RestControllerAdvice
public class GlobalExceptionAdvice {
     

    /**
     * 校验失败异常处理
     * @param e 异常类
     * @return  com.fxt.common.utils.R
     * @author  fuxintong
     * @date  2021/1/26 15:58
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R validHander(MethodArgumentNotValidException e){
     
        log.error("异常信息{},异常类:{}",e.getMessage(),e.getClass());
        BindingResult result = e.getBindingResult();
        Map<String,Object> resMap = new HashMap<>(10);
        if (result.hasErrors()) {
     
            result.getFieldErrors().forEach(fieldError -> {
     
                resMap.put("字段:"+fieldError.getField(),"异常:"+fieldError.getDefaultMessage());
            });
        }
        return R.error(ExceptionCodeEnum.VAILID.getCode(),ExceptionCodeEnum.VAILID.getMessage()).put("data",resMap);
    }
}

过程

在发现统一异常处理类不起作用后,开始寻找原因,一开始以为是@RestControllerAdvice注解的使用方法不对造成的,但百度了一波发现,并没有任何问题。

因为我的异常处理类是单独放在了公共服务中common下,所以我将这个异常处理类,放到业务服务下进行测试。使用Postman进行测试返回如下

记录一次统一异常处理类不生效的解决方案_第1张图片

根据结果来看,放在业务服务下,异常处理类好用的,但放在公共服务时却不好用,当时就很疑惑记录一次统一异常处理类不生效的解决方案_第2张图片

就在我疑惑中瞎点代码时候,有个重大发现记录一次统一异常处理类不生效的解决方案_第3张图片 如下图:

记录一次统一异常处理类不生效的解决方案_第4张图片

记录一次统一异常处理类不生效的解决方案_第5张图片

以上两图比对,会发现画红框的地方异常处理类的地方缺少一个小图标,那个图标意思是 该类注册到了Spring 容器中;使用 @Component将类中注册到Spring 容器后的就会出现这个小图标。因为 SpringBoot 本身在启动类上会使用 @SpringBootApplication 进行标注这是个启动类,并且会扫描启动类所在路径下的所有组件信息。@SpringBootApplication 源码如下:

@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration

// 此处就是扫描启动类路径下的所有 组件。
@ComponentScan(
    excludeFilters = {
     @Filter(
    type = FilterType.CUSTOM,
    classes = {
     TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
     AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
     
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {
     };
 }

发现以上问题后,查找我的项目发现,我的统一异常处理类所在路径业务服务启动类所在的路径不同,导致当业务服务启动时没有扫描到,统一异常类才会出现 @RestControllerAdvice的不起作用;路径如下图

记录一次统一异常处理类不生效的解决方案_第6张图片

解决

两种方法解决:

  • 将统一异常处理类的层级改成跟业务服务一样,都改成com.fxt.mall.xxxxx(推荐此方法)
  • 在启动类上定义扫描包的路径
//此处写上要扫描包的路径
@SpringBootApplication(scanBasePackages = {
     "com.fxt.mall","com.fxt.common"})
@MapperScan("com.fxt.mall.product.dao")
@EnableDiscoveryClient
@EnableFeignClients
public class SmallMallProductApplication {
     

    public static void main(String[] args) {
     
        SpringApplication.run(SmallMallProductApplication.class, args);
    }

}

一个在码农道路上孤独行走的人

微信搜索【Java猿记】

你可能感兴趣的:(BUG记录总结,java,spring,boot,spring)