提高篇——优雅处理springboot项目中的异常 自定义注解结合AOP实现全局异常处理

问题场景:

在项目开发中,出现的一些异常是可以预见的
最简单的做法就是使用try catch去处理这些异常
问题 业务代码太多的try catch使得代码不简洁,可读性变差


问题思考:

那么有没有一种方法,可以把这些异常进行统一处理以及日志输出呢?答案是有的。
自定义注解 + AOP + AbstractErrorController

分部说明:

1、首先我们定义一个自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    
    //注解使用的位置
    String location();

    //使用的相关信息
    String msg() default "";

}

2、接着去编写aop切面

@Aspect
@Component
public class MyAop {

				//这里注解的路径不能错
    @Pointcut("@annotation(com.study.practice.aop4Exception.MyAnnotation)")
    public void access(){
    }
    
    @AfterThrowing(pointcut = "access()",throwing = "e")
    public void afterThrowing(Exception e){
       
            System.out.println("something wrong");
    }

}

3、在方法上使用注解

@Service
public class TestService {

    @MyAnnotation(msg = "试一试",location = "testService")
    public void myTest(){
        System.out.println("myTest");
        int i = 1/0;
    }
    
}

4、在controller调用这个service (略)

注意:
好像必须启动项目aop才能生效,这可能和注解的runtime时生效有关,但我用springboot test直接测试是不行的


访问接口
提高篇——优雅处理springboot项目中的异常 自定义注解结合AOP实现全局异常处理_第1张图片
可以看出,成功进入异常处理,但仍然有异常抛出,这是因为aop并不能完全处理异常,异常仍会向上层调用者抛出。


问题不大,我们继续改善他


5、编写异常的处理类

@RestController
@ControllerAdvice
public class GlobalExceptionHandler extends AbstractErrorController {

    public GlobalExceptionHandler(ErrorAttributes errorAttributes) {
        super(errorAttributes);
    }
    @Override
    public String getErrorPath() {
        return null;
    }
    
    @ExceptionHandler(Exception.class)   //制定你要用这个方法处理什么类型的异常
    public String handle(Exception e){
        System.out.println(e.getMessage());

        return "服务器错误";
    }
    
}

提高篇——优雅处理springboot项目中的异常 自定义注解结合AOP实现全局异常处理_第2张图片
这样就可以在返回对前端友好数据的同时,记录异常情况并且处理,比如发生异常后发送邮件,消息通知开发,运维人员

补充 如何获取注解中的参数

@Aspect
@Component
public class MyAop {


    @Pointcut("@annotation(com.study.practice.aop4Exception.MyAnnotation)")
    public void access(){
    }

    @AfterThrowing(pointcut = "access()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint,Exception e){

        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        MyAnnotation myAnnotation = signature.getMethod().getAnnotation(MyAnnotation.class);

        String location = myAnnotation.location();
        String msg = myAnnotation.msg();

        System.out.println("location:" + location + "  ,msg:" + msg);

        System.out.println("something wrong");
    }

}

提高篇——优雅处理springboot项目中的异常 自定义注解结合AOP实现全局异常处理_第3张图片
获取成功,掌握到这里,我们已经可以实现很多东西了,具体各位可以根据各自业务进行拓展。

你可能感兴趣的:(java,spring,boot,aop)