同事说不会在SpringBoot中集成日志记录操作我向他推荐了这篇文章

SpringBoot中记录操作日志

记一次SpringBoot中记录管理员的操作日志,记录管理员对用户、管理员、分类、视频等模块的操作,如:删除管理员、用户、视频、修改密码、信息等等,都需要被记录下来业务实现:

  • 基于Spring AOP实现
  • 注册自定义注解
package com.wanshen.annocation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
//可以用在类和方法上
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
public @interface Logger {
    String methodName();
}
  • 创建切面类--AddLog
package com.wanshen.aspect;

import com.wanshen.annocation.Logger;
import com.wanshen.entity.Vo;
import com.wanshen.entity.YxAdmin;
import com.wanshen.entity.YxLog;
import com.wanshen.service.YxLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;


/**
 * @author WanShen
 * @date 2019年12月04日 9:14
 */
@Aspect
@Component
@Slf4j
public class AddLog {
    @Resource
    private HttpSession session;
    @Resource
    private YxLogService yxLogService;

    @AfterReturning(value = "@annotation(com.wanshen.annocation.Logger)", returning = "result")
    public void addLogger(JoinPoint point, Vo result) {
        YxLog yxLog = new YxLog();
        //获取方法名
        String methodName = point.getSignature().getName();
        //获取目标类
        Class targetClass = point.getTarget().getClass();
        //获取所有的方法
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method method : methods) {
            //与当前方法名对比获取对应注解值
            if (method.getName().equals(methodName))
                //将数据存入
                yxLog.setMethodName(method.getAnnotation(Logger.class).methodName());
        }
        //如果存储方法名
        // yxLog.setMethodName(methodName);
        //    获取管理员姓名
        YxAdmin login = (YxAdmin) session.getAttribute("login");
        String adminName = login.getUsername();
        Date createTime = new Date();
        //赋值给log
        yxLog.setAdminName(adminName).setCreateTime(createTime);
        log.debug(result.isStatus() + "===");
        //操作成功
        if (result.isStatus()) yxLog.setOptionStatus(1);
            //操作失败
        else yxLog.setOptionStatus(0);
        //    存入数据库
        yxLogService.addLog(yxLog);
    }
}

注:自定义注解应该在controller中使用,根据返回的结果进行判断操作的成功或者失败。

  • 补充:

在上述代码中 获取方法注解上的参数使用了循环 根据获取的方法名称和所有的方法进行比较 符合则获取该方法注解上的值, 后期做了以下修改

  • 问题区域

问题区域图片

  • 更改之后应该为:
 		//获取方法签名信息从而获取方法名和参数类型
        MethodSignature methodSignature =(MethodSignature)  point.getSignature();
        //获取目标类
        Class targetClass = point.getTarget().getClass();
        //通过签名信息 获取方法的名称和所有参数
        Method method = targetClass.getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        //将获取到注解的值填入到对象中
        yxLog.setMethodName(method.getAnnotation(Logger.class).methodName());
  • 通过查看源码可以看到 该方法需要两个参数(方法名称,参数属性) 之前出现异常因为没有给参数属性赋值
	//源码如下:
	@CallerSensitive
	//需要两个参数: 方法名称,参数属性
    public Method getMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        Method method = getMethod0(name, parameterTypes, true);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }
posted @ 2023-01-05 20:07  万神·  阅读(96)  评论(0编辑  收藏  举报