SpringBoot自定义注解之实现AOP切面日志详解

2022-09-03 15:49:21 58 0
魁首哥

通过自定义注解的方式(如:@SysLog(obj = "操作对象", text = "操作内容"),在 SpringBoot 中来实现 AOP 切面统一打印出入参日志。

一、先看下项目结构

二、Maven JAR依赖

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

三、自定义注解

@SysLog

import Java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SysLog {

  /**
  * 操作对象
  * **/
  String obj() default "";

  /**
  * 操作内容
  * **/
  String text() default "";
}

四、AOP切面

import java.lang.reflect.Method;

import com.zxk.demo.annotation.SysLog;
import org.ASPectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;


@SuppressWarnings("all")
@Aspect
@Component
public class SysLogAspect {

  // 切入点
  @Pointcut(value = "@annotation(com.zxk.demo.annotation.SysLog)")
  private void pointcut() {
  }

  /**
  * 在方法执行前
  * @param point
  * @param myLog
  * @return
  */
  @Before(value = "pointcut() && @annotation(sysLog)")
  public void before(SysLog sysLog){
    System.out.println("++++执行了before方法++++");
  }


  /**
  * 在方法执行前后
  * @param point
  * @param myLog
  * @return
  */
  @Around(value = "pointcut() && @annotation(sysLog)")
  public Object around(ProceedingJoinPoint point, SysLog sysLog) {
    System.out.println("++++执行了around方法++++");
    String obj = sysLog.obj();
    String text = sysLog.text();
    // 拦截的类名
    Class clazz = point.getTarget().getClass();
    // 拦截的pXlBL方法
    Signature sig = point.getSignature();
    MethodSignature msig = null;
    if (!(sig instanceof MethodSignature)) {
      throw new IllegalArgumentException("该注解只能用于方法");
    }
    msig = (MethodSignature) sig;
    Object target = point.getTarget();
    Method currentMethod;
    try {
      currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
      System.out.println("执js行了类:" + clazz.getSimpleName());
      System.out.println("方法:" + currentMethod.getName());
      System.out.println("自定义注解:" + obj+"==="+text);
    } catch (Exception e) {
      e.printStackTrace();
    }
    try {
      return point.proceed(); //执行程序
    } catch (Throwable throwable) {
      throwable.printStackTrace();
      return throwable.getMessage();
    }
  }

  /**
  * 方法执行后
  * @param joinPoint
  * @param myLog
  * @param result
  * @return
  */
  @AfterReturning(value = "pointcut() && @annotation(sysLog)", returning = "result")
  public Object afterReturning(JoinPoint joinPoint, SysLog s恰卡编程网ysLog, Object result) {
    // HttpServletRequest request = ((ServletRequestAttributes)
    // RequestContextHolder.getRequestAttributes()).getRequest();
    // HttpSession session = request.getSession();
    /**
    * 将信息保存到数据库
    * **/
    System.out.println("++++执行了afterReturning方法++++");
    System.out.println("自定义注解:" + sysLog.obj()+"=="+sysLog.text());
    System.out.println("执行结果:" + result);
    return result;
  }

  /**
  * 方法执行后 并抛出异常
  * @param joinPoint
  * @param myLog
  * @param ex
  */
  @AfterThrowing(value = "pointcut() && @annotation(sysLog)", throwing = "ex")
  public void afterThrowing(JoinPoint joinPoint, SysLog sysLog, Exception ex) {
    System.out.println("++++执行了afterThrowing方法++++");
    System.out.println("请求:" + sysLog.text() + " 出现异常");
  }
}

五、Controller层实现

@SysLog(obj = "操作对象", text = "操作内容")
@GetMapping("/index")
  public String hello() {
//    int num = 5/0;
//    System.out.println("执行结果:" + num);
    return "hello word";
  }

六、测试

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

收藏
分享
海报
0 条评论
58
上一篇:SpringBoot集成POI导出Execl表格之统一工具类 下一篇:SpringBoot+Quartz实现动态定时任务

本站已关闭游客评论,请登录或者注册后再评论吧~

忘记密码?

图形验证码