使用SpringAOP来捕获异常

本文介绍了一种利用AOP技术自动捕获并打印方法异常及其参数的方法,通过自定义注解和切面,实现对异常信息的详细记录,便于问题排查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们在开发程序的时候,经常遇到方法抛异常,而有时候异常打印出来的信息又不够完整,这时候,可以通过AOP,自动在抛异常的时候将方法传入的参数给打印出来。

实现步骤:

1.自定义注解作为连接点(当然也可以用其他方式指定连接点,我觉得使用注解是个不错的注意)

2.定义一个AOP切面

3.在需要捕获异常的方法上面,添加注解

 

自定义注解

/**
 * 异常自动捕获
 * 注解在方法上,当方法中抛出异常的时候,打印出方法以及方法的参数,方便排查
 * @see ExceptionCatchAop
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionCatch {
    /**
     * 如果没有指定该值,则打印的方法名称为 '类名#方法名'
     * @return 自定义名称
     */
    String value() default "";
}

定义切面,可以通过配置文件中指定exception.catch.switch=1/0,来打开或关闭异常捕获功能

@Component
@Aspect
@ConditionalOnProperty(name = "exception.catch.switch", havingValue = "1")
public class ExceptionCatchAop {
    @Around("@annotation(exceptionCatch)")
    public Object around(ProceedingJoinPoint joinPoint, ExceptionCatch exceptionCatch) throws Throwable{
        try{
            return joinPoint.proceed();
        }catch (Throwable throwable){
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

            String value = exceptionCatch.value();
            if(StringUtils.isEmpty(value)){
                value = methodSignature.getMethod().getDeclaringClass().getName()+"#"+
                        methodSignature.getMethod().getName();
            }
            String[] paramterNames = methodSignature.getParameterNames();
            Object[] args = joinPoint.getArgs();
            StringBuilder sb = new StringBuilder();
            sb.append("【").append(value).append("】")
                .append("调用异常, 异常参数【");
            if(paramterNames.length>0){
                for(int i=0;i<paramterNames.length;i++){
                    sb.append(paramterNames[i]).append(" : ").append(args[i]);
                    if(i<paramterNames.length-1){
                        sb.append(",");
                    }
                }
            }
            sb.append("】");
            System.err.println(sb);
            throw throwable;
        }
    }
}

3.在需要的地方使用,添加上注解即可

效果

还可以指定方法的别名

效果

这样,报错的时候,就能看到方法传入的参数,方便排查问题了

如果程序上线了,不需要异常捕获了,再从配置文件中把开关关掉即可。

### 使用 Spring AOP `@AfterThrowing` 注解捕获异常 为了利用 `@AfterThrowing` 注解来捕获并处理应用程序中的异常,需创建一个切面类,并在其中定义带有此注解的方法。该方法会在被拦截的方法抛出特定类型的异常时触发。 #### 创建 Aspect 类 首先,确保项目已引入了 `spring-boot-starter-aop` 依赖项[^2]: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version>2.1.4.RELEASE</version> </dependency> ``` 接着,编写一个方面(Aspect)类用于捕捉异常: ```java import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class ExceptionHandlingAspect { /** * 当com.example.service包下的任何服务层组件内的任意公共成员函数发生异常时, * 将会调用本方法进行统一的日志记录或其他业务操作。 */ @AfterThrowing( pointcut = "execution(* com.example.service..*.*(..))", throwing = "exception" ) public void logException(Throwable exception) { System.err.println("An error occurred: " + exception.getMessage()); // 可在此处添加更多复杂的错误处理逻辑,如发送邮件报警、写入数据库等 } } ``` 上述代码片段展示了如何配置切入点表达式以及指定要监听的异常对象名称参数 `throwing="exception"`。每当匹配的服务层方法抛出了未被捕获异常实例时,就会自动回调 `logException()` 方法来进行相应的处理工作[^1]。 此外,还可以进一步定制化异常处理器的行为模式,例如只针对某些具体的异常类型做出反应;或是结合其他AOP通知机制共同作用于同一个连接点之上等等[^3]。 #### 测试效果 假设存在如下简单的Service接口及其实现类: ```java @Service public class SampleServiceImpl implements SampleService { @Override public String performOperation() throws RuntimeException { throw new RuntimeException("Simulated runtime failure"); } } ``` 当调用了 `performOperation()` 并引发了运行时异常后,控制台将会输出由 `ExceptionHandlerAspect.logException()` 所打印的信息:“An error occurred: Simulated runtime failure”。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值