AOP实现异常记录日志

1、导包

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2、自定义注解

package com.leo.annotate;

import java.lang.annotation.*;

/**
 * @author Leo
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ExceptionLogAnnotate {
    String code() default "";
    String name() default "";
    String errorName() default "";
}

3、定义切片类,并实现相关逻辑处理

package com.leo.aspect;

import com.leo.annotate.ExceptionLogAnnotate;
import com.leo.cache.JvmLruOneCacheComponent;
import com.leo.dto.ErrorInfoResDto;
import com.leo.service.ErrorInfoService;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author Leo
 */
@Aspect
@Component
public class ExceptionLogAspect {

    @Resource
    private ErrorInfoService errorInfoService;
    @Resource
    private JvmLruOneCacheComponent cacheUtil;

    /**
     * 获取方法上的注解
     */
    public static ExceptionLogAnnotate getExceptionLogAnnotate(JoinPoint jp) throws Exception {
        ExceptionLogAnnotate o = null;
        // 拿到切点的类名,方法名,方法参数
        String className = jp.getTarget().getClass().getName();
        String methodName = jp.getSignature().getName();
        // 获取参数数组
        Object[] args = jp.getArgs();
        Class<?> targetClass = Class.forName(className);
        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equalsIgnoreCase(methodName)) {
                Class<?>[] clazzs = method.getParameterTypes();
                if (clazzs.length == args.length) {
                    o = method.getAnnotation(ExceptionLogAnnotate.class);
                }
            }
        }
        return o;
    }

    @Pointcut(value = "@annotation(com.leo.annotate.ExceptionLogAnnotate)")
    public void pointCut() {
    }

    /**
     * 定义了一个异常通知,这个通知对上面定义的pointCut()切入点中的所有方法有效
     */
    @AfterThrowing(value = "pointCut()",throwing = "e")
    public void logAfterThrowing(JoinPoint joinPoint,Exception e) throws Exception {
        ExceptionLogAnnotate ela = getExceptionLogAnnotate(joinPoint);
        String msgInfo = e.getMessage() + "\r\n" + Arrays.toString(e.getStackTrace());
        ErrorInfoResDto errorDto = ErrorInfoResDto.buildDto(ela.code(), ela.name(), ela.errorName(), msgInfo);
        //保存到数据库
        errorInfoService.asyncCreateErrorInfo(errorDto);
    }
}

4、使用。在方法上加上注解。(自调方法不生效)

    @Override
    @ExceptionLogAnnotate(errorName= "test")
    public void logErrTest() {
        getDataTest(item);
    }

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AOP(面向切面编程)可以帮助我们在程序运行时动态地添加一些额外的功能。在记录日志异常拦截方面,使用 AOP 可以让我们更方便地实现这些功能,而不需要在每个方法中都手动添加相应的代码。 记录日志方面,我们可以使用 AOP 将 LogAspect(日志切面)应用到需要记录日志的方法上。LogAspect 可以在方法执行前、执行后或抛出异常记录相关日志信息。 异常拦截方面,我们可以使用 AOP 将 ExceptionAspect(异常切面)应用到需要拦截异常的方法上。ExceptionAspect 可以捕获方法执行过程中抛出的异常,并进行相应的处理,如记录日志、提示用户等。 下面是一个使用 AOP 记录日志异常拦截的示例代码: ```java @Aspect @Component public class LogAspect { private final Logger logger = LoggerFactory.getLogger(LogAspect.class); @Before("execution(* com.example.demo.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { logger.info("Before method: " + joinPoint.getSignature().getName()); } @AfterReturning("execution(* com.example.demo.service.*.*(..))") public void logAfterReturning(JoinPoint joinPoint) { logger.info("After method: " + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "execution(* com.example.demo.service.*.*(..))", throwing = "ex") public void logAfterThrowing(JoinPoint joinPoint, Exception ex) { logger.error("Exception in method: " + joinPoint.getSignature().getName(), ex); } } @Aspect @Component public class ExceptionAspect { private final Logger logger = LoggerFactory.getLogger(ExceptionAspect.class); @Around("execution(* com.example.demo.service.*.*(..))") public Object handleException(ProceedingJoinPoint joinPoint) throws Throwable { try { return joinPoint.proceed(); } catch (Exception ex) { logger.error("Exception in method: " + joinPoint.getSignature().getName(), ex); // 处理异常,如记录日志、提示用户等 throw ex; } } } ``` 在上面的代码中,LogAspect 和 ExceptionAspect 分别实现记录日志异常拦截的功能。我们将它们添加到需要记录日志和拦截异常的方法上即可。例如,我们可以在需要记录日志的 service 方法上添加 @Before、@AfterReturning 和 @AfterThrowing 注解,或在需要拦截异常的方法上添加 @Around 注解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值