AOP切面增加日志记录功能Demo

自定义注解 @AddUpdateLog

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AddUpdateLog {
}

自定义用于成员属性的注解@FieldInterface,作用稍后便知

@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInterface {
    String name() default "";

    String convertField() default "";
}

原业务代码:

	@Override
    @AddUpdateLog
    public ItemResult<Long> saveOrUpdateProcess(Request<ProcessFormDTO> request) {
        Long result = null;
        if (request.getData().getId() != null) {
            processBiz.updateProcess(request.getData());
            result = request.getData().getId();
        } else {
            ProcessFormDTO data = request.getData();
            data.setCreateManager(request.getActionInfo().getUserId().longValue());
            data.setCreateManagerName(request.getActionInfo().getNickname());
            result = processBiz.createProcess(request.getData());
        }
        return new ItemResult<>(result);
    }

其中入参属性:

public class ProcessFormDTO implements Serializable {
   
    private Long id;
    
    @FieldInterface(name = "申请流程")
    private String processName;
    
    @FieldInterface(name = "申请流程说明")
    private String description;
    
    private Long categoryId;
    
    @FieldInterface(name = "审核类型")
    private String categoryName;
    
    @FieldInterface(name = "审核流程说明",convertField = "isCallback")
    private Byte processType;
    
    private Long createManager;
    
    @FieldInterface(name = "创建人")
    private String createManagerName;
    
    private Long ownerManager;
    
    @FieldInterface(name = "归属人")
    private String ownerManagerName;
    
    private Long ownerGroup;
    
    @FieldInterface(name = "归属人组织")
    private String ownerGroupName;
}

AOP核心代码:

/**
 * 审核流程日志记录
 *
 * @author 
 */
@Aspect
@Component
public class AuditLog {

    private Logger logger = LoggerFactory.getLogger(AuditLog.class);

    @Resource
    private IAuditProcessMapper auditProcessMapperSlave;
    @Resource
    private ILogBiz logBiz;

    /**
     * 日志记录切入点
     */
//    @Pointcut("execution(* com.ipr.biz.impl.ProcessBizImpl.updateProcess(..))")
    @Pointcut("@annotation(com.ipr.audit.aop.AddUpdateLog)")
    public void doLog() {
    }

    /**
     * 后置通知
     */
    @AfterReturning("doLog()")
    public void after(JoinPoint point) throws Exception {
        AuditLogDO auditLogDO = new AuditLogDO();
        // 接口请求参数
        Request args = (Request) point.getArgs()[0];
        ActionInfo actionInfo = args.getActionInfo();
        String operator = "SYSTEM";
        Integer operatorId = 0;
        if (!Objects.isNull(actionInfo)) {
            operator = actionInfo.getNickname();
            operatorId = actionInfo.getUserId();
        }
        auditLogDO.setOperatorId(operatorId.longValue());
        auditLogDO.setOperatorName(operator);
        // 变更详情
        StringBuffer changeDetail = new StringBuffer(operator);

        Field[] fields = null;
        Object original = new Object();
        if (args.getData() instanceof ProcessFormDTO) {
            ProcessFormDTO arg = (ProcessFormDTO) args.getData();
            AuditProcessDO auditProcessDO = ProcessConvert.fromProcessFormDTO(arg);
            auditLogDO.setProcessId(auditProcessDO.getProcessId());
            original = auditProcessMapperSlave.getAuditProcessByProcessId(auditProcessDO.getProcessId());
            Class<? extends ProcessFormDTO> cls = arg.getClass();
            fields = cls.getDeclaredFields();
        } else if (...) {
            ...
        }
        assert fields != null;
        for (Field f : fields) {
            // 判断属性上是否上存在注解
            boolean annotationPresent = f.isAnnotationPresent(FieldInterface.class);
            f.setAccessible(true);
            String fName = f.getName();
            Object newValue = f.get(args.getData());
            if (annotationPresent && newValue != null) {
                System.out.println("属性名:" + fName + " 属性值:" + newValue);
                FieldInterface fieldDescription = f.getAnnotation(FieldInterface.class);
                // 获取注解值
                String nameStr = fieldDescription.name();
                String convertField = fieldDescription.convertField();
                System.out.println(nameStr);
                // 反射获取旧值
                String getLetters = "";
                if (StringUtils.isEmpty(convertField)) {
                    getLetters = fName.substring(0, 1).toUpperCase() + fName.substring(1);
                } else {
                    getLetters = convertField.substring(0, 1).toUpperCase() + convertField.substring(1);
                }
                String getter = "get" + getLetters;
                Method method = original.getClass().getMethod(getter);
                Object value = method.invoke(original);
                if (value instanceof Boolean) {
                    changeDetail.append("将").append(nameStr).append("由:\"").append(value).append("\"变更为:\"").append(newValue.equals(1)).append("\";\n");
                } else {
                    changeDetail.append("将").append(nameStr).append("由:\"").append(value).append("\"变更为:\"").append(newValue).append("\";\n");
                }
            }
        }

        System.out.println(changeDetail);
        auditLogDO.setOperateDetail(changeDetail.toString());
        // mysql入库
        addLogs(auditLogDO);
        System.out.println("==============监听到更新流程===============");
        System.out.println("==============更新流程====================");
        System.out.println("==============流程=======================");
        System.out.println("==============程=========================");
    }

    /**
     * 环绕通知
     */
//    @Around("doLog()")
    public void around(ProceedingJoinPoint point) {
        Object arg = null;
        System.out.println("************* 环绕前..... *************");
        System.out.println(point);
        //得到参数
        Object[] args = point.getArgs();
        System.out.println("args=> " + Arrays.toString(args));
        System.out.println(args[0] instanceof ProcessFormDTO);
        if (args[0] instanceof ProcessFormDTO) {
            ProcessFormDTO dto = (ProcessFormDTO) args[0];
            System.out.println(JSON.toJSONString(dto.getId()));
        }
        // 得到切入点的类型
        String kind = point.getKind();
        System.out.println("kind => " + kind);
        // 切入点 得到被增强方法的方法签名
        MethodSignature methodSignature = (MethodSignature) point.getSignature();

        // 方法名 到被增强方法的方法
        Method method = methodSignature.getMethod();
        System.out.println("method => " + method);

        // 方法名 到被增强方法的方法 上面的注解
        Signature signature = point.getSignature();
        String name = signature.getName();
        Class declaringType = signature.getDeclaringType();
        int modifiers = signature.getModifiers();
        String declaringTypeName = signature.getDeclaringTypeName();
        System.out.println("    name => " + name + "\\\n    declaringType => "
                + declaringType + "\\\n    modifiers => " + modifiers + "\\\n    declaringTypeName => " + declaringTypeName);
        System.out.println("signature => " + signature);
        // 得到目标
        Object target = point.getTarget();
        System.out.println("target => " + target);

        System.out.println("************* 环绕后 *************");
    }

    /**
     * 日志表新增记录
     *
     * @param auditLogDO
     */
    private void addLogs(AuditLogDO auditLogDO) {
//        Request<AuditLogDO> request = new Request<>(auditLogDO);
        int i = logBiz.insertAuditLog(auditLogDO);
        System.out.println(i);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值