统一异常处理:基于xml的AOP统一异常处理

项目背景:
2021年前半年主要处理一些线上Bug,2021下半年主要进行一些系统优化。项目比较老,处于升级ing,很多地方需要重构,其中有一些服务还没有前后端分离,依然使用tomcat,因为系统用户比较多,每日单量非常大,当线上前端出现一个异常信息时,若根据该信息去web搜索就会出现很多,(比如,租户给客服反应某某场景出现了‘系统异常’,然后值班人员去web搜索‘系统异常’的日志,会匹配很多日志,需要人力的筛选),给问题的定位带来了困难,为了提高问题定位的速度,后来架构组提出做三件事:
1、去除原来自定义的异常BusinessException,使用Java自带的非法参数异常java.lang.IllegalArgumentException;
2、去除controller层的try-catch;
3、针对Controller层返回值类型是Result的做统一异常处理;

任务交给我来负责,首先针对前两个任务,本来准备打算写一个批处理去改,但是涉及项目过多,每个项目又比较大,代码量比较多,使用批处理修改文件后,依然得需要人工去合验才能放心,再加上当时来了六七个实习生,和架构组协商后,统一由实习生们来完成这两个子任务,最终一周完成,并部署到测试环境;

我的工作就剩下子任务3,我采用的是 基于xml配置的AOP统一异常处理, 首先我将统一异常处理逻辑写到了common项目中,因为每个项目都引了common的依赖,然后在使用到的项目中通过xml文件配置切面和切入点,切入点尽可能的细化,拦截到异常后,在提示信息后面追加特征码(UUID),当页面出现异常提示信息后,直接将前端提示的特征码给值班人员,就可以根据特征码实现问题的快速定位;

下面展示common项目中的 异常处理的逻辑

//省略包结构和导入信息

/**
 * @ClassName StandardControllerExceptionExecuteAroundAdvice
 * @Description 标准Controller层异常处理 环绕通知,注意:只处理返回值类型是Result
 * @Author 张志文
 * @Date 2021/8/5 21:11
 **/
public class StandardControllerExceptionExecuteAroundAdvice {
    private final static Logger LOGGER = LoggerFactory.getLogger(StandardControllerExceptionExecuteAroundAdvice.class);

    public Result around(ProceedingJoinPoint joinPoint) {
        Result result;
        try {
            result = (Result)joinPoint.proceed();
            return result;
        } catch (Throwable throwable) {
            //随机生成特征码 featureCode
            UUID uuid = UUID.randomUUID();
            String featureCode = ",特征码"+uuid.toString().substring(0,8);
            //分类处理异常信息
            if (throwable instanceof IllegalArgumentException || throwable instanceof BusinessException) {
                result =  ResultUtil.getIllegalArgumentResult(throwable.getMessage()+featureCode);
            }else {
                result = ResultUtil.getExceptionResult("系统异常"+featureCode);
            }
            //获取路径信息
            MethodSignature ms = (MethodSignature)joinPoint.getSignature();;
            Method method = ms.getMethod();
            //将异常信息追加到log
            LOGGER.error(MessageFormat.format("【特征码{0}】方法签名:{1},异常信息:{2}", uuid,method,throwable.getMessage()), throwable);
            return result;
        }
    }
}

然后在做切面的web添加相关的配置即可。
下面展示一些 出库页面的controller层针对Result返回值的AOP配置

    <!-- Controller层统一异常处理注入,只处理返回值类型Result的 -->
    <bean id="StandardControllerExceptionExecuteAroundAdvice" class="com.jd.base.common.advice.StandardControllerExceptionExecuteAroundAdvice"/>

    <!-- 配置AOP -->
    <aop:config  proxy-target-class="true">
        <!-- 配置切入点 -->
        <aop:pointcut id="controllerPoint1"
                      expression="execution(public com.jd.jcloud.wms.domain.dto.Result com.jd.jcloud.wms.pickingplan..*(..))"/>
        <aop:pointcut id="controllerPoint2"
                      expression="execution(public com.jd.jcloud.wms.domain.dto.Result com.jd.controller..*(..))"/>
        <!-- 配置切面 -->
        <aop:aspect id="controllerExceptionAspect" ref="StandardControllerExceptionExecuteAroundAdvice">
            <aop:around  method="around" pointcut-ref="controllerPoint1"/>
            <aop:around  method="around" pointcut-ref="controllerPoint2"/>
        </aop:aspect>
    </aop:config>

到此为止,基于AOP的统一异常处理就打开完了,部署到test环境验证,没问题,然后灰度,最后生产。

欢迎大家一起讨论~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值