AOP实现异常记录日志

1、导包

        
            org.springframework.boot
            spring-boot-starter-aop
        

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);
    }

你可能感兴趣的:(java,spring,boot)