aop在项目中的应用

最近因为公司业务的原因,需要对用户登录,用户注销登录、用户创建、应用创建、应用编辑、应用删除、应用打开等等地方加入日志,用于记录活动轨迹。最简单的实现方式,在所有的需要日志的接口中加入写日志的代码。日志需要包括:什么模块,干了什么,入参是什么,成功与否,如果失败,失败原因是什么。考虑到上面这些要素,对应不同模块的接口,代码实现起来比较繁琐,而且失败原因,如果是非预期的运行时异常,很难记录下来。下面用一种比较优雅的方式,实现业务需求。
主要用到的技术:AOP

step1: 自定义注解

/**
 * @Author: zzh
 * @Date: 2020/7/2 14:33
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    String operateType() default "";
    String operateContent() default "";
}

step2:将自定义注解加在需要记录日志的方法上

    @Override
    @OperationLog(operateType = "桌面", operateContent = "创建桌面")
    public String addVm(MemberDto dto) {
   	  //此处省略一万字 
    }

step3:定义切面

package com.xietong.phoenix.aspect;

import com.google.gson.Gson;
import com.xietong.phoenix.common.utils.GennerateUtil;
import com.xietong.phoenix.module.log.entity.SysUserLog;
import com.xietong.phoenix.module.log.service.LogService;
import com.xietong.sns.application.LoginUserService;
import com.xietong.sns.domain.model.system.LoginCredential;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: zzh
 * @Date: 2020/7/2 14:31
 */
@Aspect
@Component
public class LogAspect {
    private ThreadLocal<SysUserLog> local = new ThreadLocal<SysUserLog>();

    @Autowired
    private LoginUserService loginUserService;

    @Autowired
    private LogService logService;

    @Pointcut("@annotation(com.xietong.phoenix.aspect.OperationLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Class<?> clazz = point.getTarget().getClass();
        method = clazz.getMethod(method.getName(), method.getParameterTypes());
        OperationLog operationLog = method.getAnnotation(OperationLog.class);

        SysUserLog sysUserLog = new SysUserLog();
        sysUserLog.setId(GennerateUtil.generateId(16));
        sysUserLog.setOperateContent(operationLog.operateContent());
        sysUserLog.setOperateType(operationLog.operateType());
        sysUserLog.setParams(Arrays.toString(point.getArgs()));
        LoginCredential loginUser = loginUserService.getLoginUser();
        if (loginUser != null) {
            sysUserLog.setOperatorName(loginUserService.getLoginUser().getRegisterName());
            sysUserLog.setOperatorId(loginUserService.getLoginUser().getId());
        }
        sysUserLog.setMethodName(point.getSignature().getName());
        local.set(sysUserLog);
        Object result = point.proceed();
        sysUserLog.setOperateResult(1);
        logService.addLog(sysUserLog);
        return result;
    }

    @AfterThrowing(pointcut = "logPointCut()", throwing = "e")
    public void afterThrowing(Throwable e) {
        SysUserLog sysUserLog = local.get();
        if (sysUserLog != null) {
            sysUserLog.setOperateResult(0);
            sysUserLog.setOperateFailReason(String.format("traceId : \":%s\"", MDC.get("traceId")));
            logService.addLog(sysUserLog);
        }
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值