java手写操作日志功能:切面实现及验证(四)

直接贴代码,干脆利落

@Aspect
@Component
public class OperationLogAspect {

/**
 * 修改内容汇总
 */
private List>>> mapArrayList = new ArrayList<>();
/**
 * 修改模块名
 */
private String module = "";

/**
 * 调用的方法路径
 */
private String methodName = "";

/**
 * 修改的实体名称
 */
private String domainName = "";

/**
 * 操作类型
 *
 * @return
 */
private String operationType = "";

@Autowired
private OperationLogService operationLogService;

@Pointcut(value = "@annotation(com.demo.operationlog.annotation.OperationLogFlag)")
public void annotationCut() {

}

@Before("annotationCut()")
public void doBefore(JoinPoint joinPoint) throws Exception {
    **//拿到注解方法和参数**
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    Object[] objects = joinPoint.getArgs();
    Object newObject = objects[0];
    **//取得注解**
    OperationLogFlag operationLogFlag = method.getAnnotation(OperationLogFlag.class);
    **//从注解中拿到各种标识字段的值**
    module = operationLogFlag.module();
    methodName = operationLogFlag.methodName();
    domainName = operationLogFlag.domainName();
    operationType = operationLogFlag.operationType();
    **//从注解中的参数拿到id的值**
    String searchInfo = operationLogFlag.searchInfo().trim();
    String fieldName = searchInfo.substring(searchInfo.indexOf(".") + 1, searchInfo.indexOf("}"));
    ****//只有修改的时候有数据对比,要设值记录**,新增删除什么的就没有改动点可以记录,少走这一步**
    if ("UPDATE".equals(operationType)) {
        List fieldValueList = ReflectionUtils.getFieldValue(newObject, fieldName);
        for (String fieldValue : fieldValueList) {
            **//拿到旧的object**
            Object oldObject = BaseObjectParse.getResult(fieldValue, operationLogFlag);
            **//开始比较**
            List> mapList = ReflectionUtils.getTwoObjectDiff(newObject, oldObject);
            **//把比较的结果汇总(map是(修改的主键id,修改结果集合))**
            Map>> map = new HashMap>>();
            map.put(fieldValue, mapList);
            mapArrayList.add(map);
        }
    }
}

@AfterReturning("annotationCut()")
public void doAfter() {
    **//后置通知把数据保存进入日志表**
    List operationLogs = new ArrayList<>();
    for (Map>> map : mapArrayList) {
        for (String moduleId : map.keySet()) {
            OperationLog operationLog = new OperationLog();
            List> changeMap = map.get(moduleId);
            String json = JSONArray.toJSONString(changeMap);
            **//给日子对象设值**
            operationLog.setModuleId(moduleId);
            operationLog.setModule(module);
            operationLog.setOperationType(operationType);
            operationLog.setOperationContext(json);
            operationLog.setDomainName(domainName);
            operationLog.setOperationDate(new Date());
            operationLogs.add(operationLog);
        }
    }
    operationLogService.insertList(operationLogs);
    mapArrayList.clear();
}

/**
 * 异常日志处理
 *
 * @param ex
 */
@AfterThrowing(throwing = "ex", pointcut = "annotationCut()")
public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
    **//从注解中的参数拿到id的值**
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    OperationLogFlag operationLogFlag = method.getAnnotation(OperationLogFlag.class);
    Object[] objects = joinPoint.getArgs();
    Object newObject = objects[0];
    String searchInfo = operationLogFlag.searchInfo().trim();
    String fieldName = searchInfo.substring(searchInfo.indexOf(".") + 1, searchInfo.indexOf("}"));
    List fieldValueList = ReflectionUtils.getFieldValue(newObject, fieldName);
    String fieldValue = ReflectionUtils.listToStr(fieldValueList);
    OperationLog operationLog = new OperationLog();
    **//给日志对象设值**
    operationLog.setModuleId(fieldValue);
    operationLog.setModule(module);
    operationLog.setOperationType(operationType);
    operationLog.setOperationContext(ex.getMessage());
    operationLog.setDomainName(domainName);
    operationLog.setOperationDate(new Date());
    operationLogService.insert(operationLog);
}

}

注:实体和数据库可以根据需求具体设计,大致思路就是以上所说的了,代码复制就可以直接使用了,不过还有很多需要改进的地方,哈哈,只是基础版1.0.0

操作日志效果如下:
正常时:
在这里插入图片描述
异常时:
在这里插入图片描述

你可能感兴趣的:(Java开发)