AOP 记录日志

package com.ipr.audit.aop;

import java.lang.annotation.*;


/**
 * @author xnALPHA
 */
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)

public @interface FieldInterface {



    String name() default "";

}
public class ProcessFormDTO implements Serializable{

    private static final long serialVersionUID = -8689138748150278713L;

    private Long id;
    /**
     * 申请流程名称
     */
    @FieldInterface(name = "申请流程名称")
    private String processName;

    /**
     * 申请流程说明
     */
    @FieldInterface(name = "申请流程说明")
    private String description;

    /**
     * 申请流程名称
     */
    @FieldInterface(name = "申请流程名称")
    private Long categoryId;

    /**
     * 审核类型名字
     */
    @FieldInterface(name = "审核类型名字")
    private String categoryName;

    /**
     * 审核流程说明(0 普通 1交互)
     */
    @FieldInterface(name = "审核流程说明")
    private Byte processType;

    /**
     * 创建人id
     */
    @FieldInterface(name = "创建人id")
    private Long createManager;

    /**
     * 创建人名称
     */
    @FieldInterface(name = "创建人名称")
    private String createManagerName;

    /**
     * 归属人id
     */
    @FieldInterface(name = "归属人id")
    private Long ownerManager;

    /**
     * 归属人名称
     */
    @FieldInterface(name = "归属人名称")
    private String ownerManagerName;

    /**
     * 归属人组织id
     */
    @FieldInterface(name = "归属人组织id")
    private Long ownerGroup;

    /**
     * 归属人组织名称
     */
    @FieldInterface(name = "归属人组织名称")
    private String ownerGroupName;
}
package com.ipr.audit.aop;

import com.alibaba.fastjson.JSON;
import com.ipr.audit.dto.process.ProcessFormDTO;
import com.ipr.dataobject.AuditProcessDO;
import com.ipr.mapper.IAuditProcessMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

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

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

    @Resource
    private IAuditProcessMapper auditProcessMapperSlave;

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

    /**
     * 后置通知
     */
    @AfterReturning("doLog()")
    public void after(JoinPoint point) throws Exception {
        StringBuffer changeDetail = new StringBuffer();
        Object[] args = point.getArgs();
        ProcessFormDTO dto = (ProcessFormDTO) args[0];
        AuditProcessDO originalAuditProcess = auditProcessMapperSlave.getAuditProcessByProcessId(dto.getId());

        Class<? extends ProcessFormDTO> cls = dto.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            String fName = f.getName();
            Object fValue = f.get(dto);
            // 判断是否方法上存在注解
            boolean annotationPresent = f.isAnnotationPresent(FieldInterface.class);
            if (annotationPresent && fValue != null) {
                System.out.println("属性名:" + fName + " 属性值:" + fValue);
                FieldInterface fieldDescription = f.getAnnotation(FieldInterface.class);
                // 获取注解值
                String nameStr = fieldDescription.name();
                System.out.println(nameStr);
            }
        }
//        Method[] methods = cls.getDeclaredMethods();
//        for (Method str : methods) {
//            // 判断是否方法上存在注解
//            boolean annotationPresent = str.isAnnotationPresent(FieldInterface.class);
//            if (annotationPresent) {
//                // 获取自定义注解对象
//                FieldInterface fieldInterface = str.getAnnotation(FieldInterface.class);
//                // 根据对象获取注解值
//                String isNotNullStr = fieldInterface.name();
//                System.out.println("------------------" + isNotNullStr);
//            }
//        }

        // todo 根据方法不同,入mongo库
        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("************* 环绕后 *************");
    }

}

开发初步完成效果:

package com.ipr.audit.aop;

import com.alibaba.fastjson.JSON;
import com.ipr.audit.dto.process.ProcessFormDTO;
import com.ipr.audit.dto.role.RoleFormDTO;
import com.ipr.audit.dto.step.AuditStepFormDTO;
import com.ipr.biz.ILogBiz;
import com.ipr.biz.convert.ProcessConvert;
import com.ipr.biz.convert.RoleConvert;
import com.ipr.biz.convert.StepConvert;
import com.ipr.dataobject.AuditLogDO;
import com.ipr.dataobject.AuditProcessDO;
import com.ipr.dataobject.AuditRoleDO;
import com.ipr.dataobject.AuditStepDO;
import com.ipr.mapper.IAuditProcessMapper;
import com.zhubajie.common.dto.ActionInfo;
import com.zhubajie.common.dto.Request;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * 审核流程日志记录
 *
 * @author xnALPHA
 */
@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 (args.getData() instanceof RoleFormDTO) {
            RoleFormDTO arg = (RoleFormDTO) args.getData();
            AuditRoleDO roleDO = RoleConvert.fromRoleFormDTO(arg);
            auditLogDO.setRoleId(roleDO.getId());
            auditLogDO.setProcessId(roleDO.getProcessId());
            Class<? extends RoleFormDTO> cls = arg.getClass();
            fields = cls.getDeclaredFields();
        } else if (args.getData() instanceof AuditStepFormDTO) {
            AuditStepFormDTO arg = (AuditStepFormDTO) args.getData();
            AuditStepDO auditStepDO = StepConvert.fromAuditStepFormDTO(arg);
            auditLogDO.setRoleId(auditStepDO.getRoleId());
            auditLogDO.setStepId(auditStepDO.getStepId());
            Class<? extends AuditStepFormDTO> cls = arg.getClass();
            fields = cls.getDeclaredFields();
        }
        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());
        // 入库
        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
    评论
AOP(面向切面编程)可以帮助我们在程序运行时动态地添加一些额外的功能。在记录日志和异常拦截方面,使用 AOP 可以让我们更方便地实现这些功能,而不需要在每个方法中都手动添加相应的代码。 记录日志方面,我们可以使用 AOP 将 LogAspect(日志切面)应用到需要记录日志的方法上。LogAspect 可以在方法执行前、执行后或抛出异常时记录相关日志信息。 异常拦截方面,我们可以使用 AOP 将 ExceptionAspect(异常切面)应用到需要拦截异常的方法上。ExceptionAspect 可以捕获方法执行过程中抛出的异常,并进行相应的处理,如记录日志、提示用户等。 下面是一个使用 AOP 记录日志和异常拦截的示例代码: ```java @Aspect @Component public class LogAspect { private final Logger logger = LoggerFactory.getLogger(LogAspect.class); @Before("execution(* com.example.demo.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { logger.info("Before method: " + joinPoint.getSignature().getName()); } @AfterReturning("execution(* com.example.demo.service.*.*(..))") public void logAfterReturning(JoinPoint joinPoint) { logger.info("After method: " + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "execution(* com.example.demo.service.*.*(..))", throwing = "ex") public void logAfterThrowing(JoinPoint joinPoint, Exception ex) { logger.error("Exception in method: " + joinPoint.getSignature().getName(), ex); } } @Aspect @Component public class ExceptionAspect { private final Logger logger = LoggerFactory.getLogger(ExceptionAspect.class); @Around("execution(* com.example.demo.service.*.*(..))") public Object handleException(ProceedingJoinPoint joinPoint) throws Throwable { try { return joinPoint.proceed(); } catch (Exception ex) { logger.error("Exception in method: " + joinPoint.getSignature().getName(), ex); // 处理异常,如记录日志、提示用户等 throw ex; } } } ``` 在上面的代码中,LogAspect 和 ExceptionAspect 分别实现了记录日志和异常拦截的功能。我们将它们添加到需要记录日志和拦截异常的方法上即可。例如,我们可以在需要记录日志的 service 方法上添加 @Before、@AfterReturning 和 @AfterThrowing 注解,或在需要拦截异常的方法上添加 @Around 注解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值