异常

全局异常介绍

https://segmentfault.com/a/1190000039024792

  • 整个系统一般我们会在一个的地方统一进行异常处理

  • 异常处理,是异常无法避免的出现了而采取的一种应急措施

    • 主要目的是对外增加友好性,对内提供补救线索;
    • 出现问题了 要有有迹可寻

方法一(@ControllerAdvice 和 @ExceptionHandler)

缺点

只能处理 controller 层抛出的异常,对例如 Interceptor(拦截器)层的异常、
定时任务中的异常、异步方法中的异常,工具类中或者其他类中的异常,并不会拦截。

方法二 (AOP)


原则:如果出现了问题一般将检查异常,转化为运行时异常.

核心原理: 动态代理思想 
采用自定义AOP的方式可以实现拦截。

  有几个关键点

定义切入点为最大项目包
采用AOP的@AfterThrowing注解获取到全局异常捕获
一个例子

package com.example.promethuesdemo.exception;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

 
    @Aspect
    @Slf4j
    @Component
    public class GlobalExceptionAspect {
        @Pointcut("execution(* com.example..*.*(..))")
        public void pointcut(){

        }

        @AfterThrowing(pointcut = "pointcut()",throwing = "e")
        public void afterThrowing(JoinPoint joinPoint,Throwable e){
            log.error("全局捕获到异常了..............");
            //纪录错误信息
            log.error("系统错误:{}", e.getMessage());
            // todo 想要执行的操作
        }

    }
  • aop中相关概念
Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它
joint point。
Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
Target(目标对象):织入 Advice 的目标对象.。 Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
Advice(增强)的类型

before advice, 在 join point 前被执行的 advice. 虽然 before advice 是在 join point 前被执行, 但是它并不能够阻止 join point 的执行, 除非发生了异常(即我们在 before advice 代码中,
不能人为地决定是否继续执行 join point 中的代码)
after return advice, 在一个 join point 正常返回后执行的 advice
after throwing advice, 当一个 join point 抛出异常后执行的 advice
after(final) advice, 无论一个 join point 是正常退出还是发生了异常, 都会被执行的 advice.
around advice, 在 join point 前和 joint point 退出后都执行的 advice. 这个是最常用的 advice.
introduction,introduction可以为原有的对象增加新的属性和方法。

  • 注意
spring AOP中的AfterThrowing增强处理可以对目标方法的异常进行处理,
但这种处理与直接使用catch捕捉处理异常的方式不同,catch捕捉意味着能完全处理异常,即只要catch块本身不抛出新的异常,
则被处理的异常不会往上级调用者进一步传播下去;但是如果使用了AfterThrowing增强处理用于对异常进行处理,
处理后异常仍然会往上一级调用者传播,如果是在main中调用的目标方法,那么异常会直接传到JVM,如下截图所示:

另外需要注意,如果目标方法中出现异常,并由catch捕捉处理且catch又没有抛出新的异常,那么针对该目标方法的AfterThrowing增强处理
将不会被执行。

上一篇:SpringAOP[4]-代理工厂


下一篇:AOP相关面试题整理