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 {@Resourceprivate ErrorInfoService errorInfoService;@Resourceprivate 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);}