springboot 基于Aop实现自定义日志管理

一、相关依赖(maven)

// 引入springboot Aop依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、代码实现

1. 添加自定义定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 1. 日志注解
 2.  3. @author xu_cxiang
 */
@Target(ElementType.METHOD) // 方法注解
@Retention(RetentionPolicy.RUNTIME) // 运行时可见
public @interface OtherLog {
    String logName();// 记录日志的名称
}

2. 定义日志实体

/**
 * 
 * <p>日志实体<p>
 *
 * @author xu_cxiang<br> 
 * @version 1.0
 *
 */
public class OtherLog {
    /**
     * 主键
     */
    private int id;
    /**
     * 日志名称
     */
    private String name;
    /**
     * 日志类型
     */
    private String type;
    /**
     * 本机ip
     */
    private String ip;
    /**
     * 用户主键
     */
    private int userId;
    /**
     * 类名称
     */
    private String className;
    /**
     * 方法名称
     */
    private String mothod;
    /**
     * 创建时间
     */
    private String createTime;
    /**
     * 是否成功
     */
    private String succeed;
    /**
     * 请求参数
     */
    private String params;
    /**
     * 备注
     */
    private String remarks;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public String getMothod() {
        return mothod;
    }
    public void setMothod(String mothod) {
        this.mothod = mothod;
    }
    public String getCreateTime() {
        return createTime;
    }
    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    public String getSucceed() {
        return succeed;
    }
    public void setSucceed(String succeed) {
        this.succeed = succeed;
    }
    public String getParams() {
        return params;
    }
    public void setParams(String params) {
        this.params = params;
    }
    public String getRemarks() {
        return remarks;
    }
    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }
    @Override
    public String toString() {
        return "OtherLog [id=" + id + ", name=" + name + ", type=" + type
                + ", ip=" + ip + ", userId=" + userId + ", className="
                + className + ", mothod=" + mothod + ", createTime="
                + createTime + ", succeed=" + succeed + ", params=" + params
                + ", remarks=" + remarks + "]";
    }
}

3. 定义日志AOP切面类(环绕通知)

import java.lang.reflect.Method;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import cn.stylefeng.guns.core.common.annotion.OtherLogAnno;
import cn.stylefeng.guns.core.util.AddressUtils;
import cn.stylefeng.guns.modular.system.model.OtherLog;

/**
 * 
 * <p>AOP日志切面类<p>
 *  * @author xu_cxiang<br> 
 * @version 1.0
 *  */
@Aspect
@Component
@Order(3)
public class OtherLogAop {
    /**
     * 环绕通知记录日志通过注解匹配到需要增加日志功能的方法
     * 
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("@annotation(cn.stylefeng.guns.core.common.annotion.OtherLogAnno)")
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        // 1.方法执行前的处理,相当于前置通知
        // 获取方法签名
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        // 获取类名
        String class_name = pjp.getTarget().getClass().getName();
        // 获取方法
        Method method = methodSignature.getMethod();
        // 获取请求参数
        String params = Arrays.toString(pjp.getArgs()).replace("[", "")
                .replace("]", "");
        // 获取方法上面的注解
        OtherLogAnno otherLogAop = method.getAnnotation(OtherLogAnno.class);
        // 获取操作描述的属性值
        String name = otherLogAop.logName();
        // 创建一个日志对象(准备记录日志)
        OtherLog log = new OtherLog();
        log.setName(name);
        log.setType("非业务日志");// 操作说明
        log.setMothod(method.getName());
        log.setClassName(class_name);
        log.setParams(params);
        log.setUserId(1);
        log.setIp(AddressUtils.getV4IP());
        log.setRemarks("");
        Object result = null;
        try {
            // 让代理方法执行
            result = pjp.proceed();
            // 2.相当于后置通知(方法成功执行之后走这里)
            log.setSucceed("成功");// 设置操作结果
        } catch (SQLException e) {
            // 3.相当于异常通知部分
            log.setSucceed("失败");// 设置操作结果
        } finally {
            // 4.相当于最终通知
            log.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));// 设置操作日期
            // 打印日志记录
            System.out.println(log.toString());
            // 在此处直接调用service插入数据库也可以。
            
            // 也可以学习guns一样利用线程池进行日志存储。
        }
        return result;
    }
}

AOP其他通知模式

* @Before 前置通知
* @After 后置通知
* @AfterReturning 后置返回通知(可以在该通知内获取请求返回数据)
* @AfterThrowing 后置异常通知

4. 使用注解记录日志

在controller或service实现层使用@OtherLogAnno注解

@Override
@OtherLogAnno(logName = "测试日志输出")
public String getLog() {
   return "success";
}

结果如下:
OtherLog :{id=0, name=测试日志输出, type=非业务日志, ip=192.168.1.1, userId=1, className=cn.stylefeng.guns.modular.system.service.impl.TestServiceImpl, mothod=getLog, createTime=2020-01-06 16:14:05, succeed=成功, params="", remarks=""}

特别声明:本文为原创作品,转载请注明出处来源!

发布了9 篇原创文章 · 获赞 16 · 访问量 2763

猜你喜欢

转载自blog.csdn.net/qq_32201423/article/details/103859766