Spring统一异常处理

在说解决方案前,首先我们要看下与切面相关的几个定义图片

JoinPoint: 程序在执行流程中经过的一个个时间点,这个时间点可以是方法调用时,或者是执行方法中异常抛出时,也可以是属性被修改时等时机,在这些时间点上你的切面代码是可以(注意是可以但未必)被注入的

Pointcut: JoinPoints 只是切面代码可以被织入的地方,但我并不想对所有的 JoinPoint 进行织入,这就需要某些条件来筛选出那些需要被织入的 JoinPoint,Pointcut 就是通过一组规则(使用 AspectJ pointcut expression language 来描述) 来定位到匹配的 joinpoint

Advice:  代码织入(也叫增强),Pointcut 通过其规则指定了哪些 joinpoint 可以被织入,而 Advice 则指定了这些 joinpoint 被织入(或者增强)的具体时机与逻辑,是切面代码真正被执行的地方,主要有五个织入时机

  1. Before Advice: 在 JoinPoints 执行前织入

  2. After Advice: 在 JoinPoints 执行后织入(不管是否抛出异常都会织入)

  3. After returning advice: 在 JoinPoints 执行正常退出后织入(抛出异常则不会被织入)

  4. After throwing advice: 方法执行过程中抛出异常后织入

  5. Around Advice: 这是所有 Advice 中最强大的,它在 JoinPoints 前后都可织入切面代码,也可以选择是否执行原有正常的逻辑,如果不执行原有流程,它甚至可以用自己的返回值代替原有的返回值,甚至抛出异常。在这些 advice 里我们就可以写入切面代码了 综上所述,切面(Aspect)我们可以认为就是 pointcut 和 advice,pointcut 指定了哪些 joinpoint 可以被织入,而 advice 则指定了在这些 joinpoint 上的代码织入时机与逻辑

画外音:织入(weaving),将切面作用于委托类对象以创建 adviced object 的过程(即代理,下文会提)。

例如:

首先我们先定义一个如下注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface GlobalErrorCatch {

}

然后将所有 service 中方法里的 「try... catch...」移除掉,在方法签名上加上上述我们定义好的注解

public class TestServiceImpl implements TestService {
   @Override
   @GlobalErrorCatch
   public ServiceResultTO<Boolean> test() {
        // 此处写服务里的执行逻辑
        boolean result = xxx;
        return ServiceResultTO.buildSuccess(result);
   }
}

然后再指定注解形式的 pointcuts 及 around advice

@Aspect
@Component
public class TestAdvice {
   // 1. 定义所有带有 GlobalErrorCatch 的注解的方法为 Pointcut
   @Pointcut("@annotation(com.example.demo.annotation.GlobalErrorCatch)")
   private void globalCatch(){}
   // 2. 将 around advice 作用于 globalCatch(){} 此 PointCut 
   @Around("globalCatch()")
   public Object handlerGlobalResult(ProceedingJoinPoint point) throws Throwable {
       try {
           return point.proceed();
       } catch (Exception e) {
           System.out.println("执行错误" + e);
           return ServiceResultTO.buildFailed("系统错误");
       }
   }

}

通过这样的方式,所有标记着 GlobalErrorCatch 注解的方法都会统一在 handlerGlobalResult 方法里执行,我们就可以在这个方法里统一 catch 住异常,所有 service 方法中又长又臭的 「try...catch...」全部干掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值