使用AOP自定义一个日志注解

添加AOP依赖

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

 自定义操作日志记录注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    public String title(); // 操作业务的功能名称
    public String operatorType(); // 操作人类别
    public int businessType(); // 业务类型(0其它;1新增;2修改;3删除)
    public boolean isSaveRequestData() default true; // 是否保存请求的参数
    public boolean isSaveResponseData() default true; // 是否保存响应的参数
}

定义一个切面类,并且在该切面类中提供一个环绕通知方法

@Aspect
@Component
public class LogAspect {

    @Resource
    private AsyncOperLogService asyncOperLogService;

    @Around("@annotation(sysLog)")
    public Object doAroundAdvice(ProceedingJoinPoint joinPoint, Log sysLog) {
        // 构建前置参数
        SysOperLog sysOperLog = new SysOperLog();

        LogUtil.beforeHandlerLog(sysLog, joinPoint, sysOperLog);

        Object proceed = null;

        try {
            proceed = joinPoint.proceed();
            // 执行业务方法
            LogUtil.afterHandlerLog(sysLog, proceed, sysOperLog, 0, null);
            // 构建响应结果参数
        } catch (Throwable e) { // 代码执行进入到catch中,业务方法执行产生异常
            e.printStackTrace(); // 打印异常信息
            LogUtil.afterHandlerLog(sysLog, proceed, sysOperLog, 1, e.getMessage());
            throw new RuntimeException();
        }

        // 保存日志数据
        asyncOperLogService.saveSysOperLog(sysOperLog);

        return proceed; // 返回执行结果
    }
}

 通过Import注解导入日志切面类到Spring容器中

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(LogAspect.class)
public @interface EnableLogAspect {
}

 在服务的启动类上添加@EnableLogAspect注解

@EnableLogAspect
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class , args) ;
    }

}

 定义一个日志实体类

@Data
public class SysOperLog {
	private String title; // 模块标题
	private String method; // 方法名称
	private String requestMethod; // 请求方式
	private String operatorType; // 操作类别(0其它 1后台用户 2手机端用户)
    private Integer businessType ; // 业务类型(0其它 1新增 2修改 3删除)
	private String operName; // 操作人员
	private String operUrl;	// 请求URL
	private String operIp; // 主机地址
	private String operParam; // 请求参数
	private String jsonResult; // 返回参数
	private Integer status;	// 操作状态(0正常 1异常)
	private String errorMsg; // 错误消息
}

定义一个Log工具类

public class LogUtil {

    // 操作执行之前调用
    public static void beforeHandlerLog(Log sysLog, ProceedingJoinPoint joinPoint, SysOperLog sysOperLog) {

        // 设置操作模块名称
        sysOperLog.setTitle(sysLog.title());
        sysOperLog.setOperatorType(sysLog.operatorType().name());

        // 获取目标方法信息
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        sysOperLog.setMethod(method.getDeclaringClass().getName());

        // 获取请求相关参数
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        sysOperLog.setRequestMethod(request.getMethod());
        sysOperLog.setOperUrl(request.getRequestURI());
        sysOperLog.setOperIp(request.getRemoteAddr());

        // 设置请求参数
        if (sysLog.isSaveRequestData()) {
            String requestMethod = sysOperLog.getRequestMethod();
            if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
                String params = Arrays.toString(joinPoint.getArgs());
                sysOperLog.setOperParam(params);
            }
        }
        sysOperLog.setOperName(AuthContextUtil.get().getUserName());
    }

    // 操作执行之后调用
    public static void afterHandlerLog(Log sysLog, Object proceed, SysOperLog sysOperLog, int status, String errorMsg) {
        // 是否保存响应的参数
        if (sysLog.isSaveResponseData()) {
            sysOperLog.setJsonResult(JSON.toJSONString(proceed));
        }
        sysOperLog.setStatus(status);
        sysOperLog.setErrorMsg(errorMsg);
    }
}
@Async // 异步执行保存日志操作
@Override
public void saveSysOperLog(SysOperLog sysOperLog) {
    sysOperLogMapper.insertSysOperLog(sysOperLog);
}

<insert id="insertSysOperLog">
    insert into sys_oper_log (id, title, method, request_method, operator_type, oper_name,
                              oper_url, oper_ip, oper_param, json_result, status, error_msg)
    values (#{id}, #{title}, #{method}, #{requestMethod}, #{operatorType}, #{operName},
            #{operUrl}, #{operIp}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg})
</insert>

使用

@Log(title = "logTest", operatorType = "管理平台", businessType = 0)
@PostMapping("/logTest")
public Result logTest() {
    // ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值