您好,欢迎来到六九路网。
搜索
您的当前位置:首页SpringBoot 更优雅的实现接口操作日志获取

SpringBoot 更优雅的实现接口操作日志获取

来源:六九路网

(1)定义 @Oplog 系统操作日志注解

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 系统操作日志注解
 */
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Oplog {

    /**
     * 系统日志处理 实现类
     */
    Class<? extends OplogHandle> value();
}


/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 系统操作日志注解
 */
@Inherited
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Oplogs {
    Oplog[] value();
}

(2)定义 OplogAop 系统日志操作 AOP 类

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 系统日志信息类
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OplogInfo implements Serializable {

    private static final long serialVersionUID = -5294793081102395594L;

    /**
     * 客户端IP
     */
    @ApiModelProperty(value = "客户端IP")
    private String ip;
}
/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 系统日志处理 接口
 */
public interface OplogHandle {

    /**
     * 系统日志处理方法钩子
     *
     * @param oplogInfo 基本操作日志信息
     * @param joinPoint 切点
     */
    void apply(OplogInfo oplogInfo, ProceedingJoinPoint joinPoint);
}
/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description AOP切面 抽象基类
 */
public abstract class AbstractAop {

    /**
     * 获取 Method 的指定注解
     *
     * @param joinPoint
     * @return T extends Annotation
     */
    protected <T extends Annotation> T getMethodAnnotation(ProceedingJoinPoint joinPoint, Class<T> clazz) {
        T annotation = null;
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Class<?>[] paramTypeArray = methodSignature.getParameterTypes();
        Method transferMoney = null;
        try {
            transferMoney = joinPoint.getTarget().getClass().getDeclaredMethod(methodSignature.getName(), paramTypeArray);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        assert transferMoney != null;
        boolean annotationPresent = transferMoney.isAnnotationPresent(clazz);
        if (annotationPresent) {
            annotation = transferMoney.getAnnotation(clazz);
        }
        return annotation;
    }

    /**
     * 获取当前类及其父类包含的指定的注解类型
     *
     * @param clazz
     * @param annotation
     * @param <T>
     * @return
     */
    protected <T extends Annotation> List<T> getInheritClassAnnotation(Class<?> clazz, Class<T> annotation) {
        List<T> list = new ArrayList<>();
        // 获取当前类及其父类包含的指定的T类型注解
        do {
            T annot = getClassAnnotation(clazz, annotation);
            if (annot != null) {
                list.add(annot);
            }
            clazz = clazz.getSuperclass();
        } while (clazz != null);
        return list;
    }

    /**
     * 获取指定类的注解
     *
     * @param clazz
     * @param annotation
     * @param <T>
     * @return
     */
    protected <T extends Annotation> T getClassAnnotation(Class<?> clazz, Class<T> annotation) {
        T res = null;
        boolean annotationPresent = clazz.isAnnotationPresent(annotation);
        if (annotationPresent) {
            res = clazz.getAnnotation(annotation);
        }
        return res;
    }
}
/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 系统日志操作 AOP
 */
@Aspect
@Component
public class OplogAop extends AbstractAop {

    @Resource
    private ApplicationContext applicationContext;

    /**
     * HttpServletRequest 请求上下文
     */
    @Resource
    protected HttpServletRequest httpServletRequest;

    /**
     * 基于方法上的注解
     */
    @Pointcut("@annotation(cn.yifants.common.extension.aop.oplog.Oplog) || @annotation(cn.yifants.common.extension.aop.oplog.Oplogs)")
    public void methodAnnotation() {
    }

    /**
     * 基于类上的注解
     */
    @Pointcut("@within(cn.yifants.common.extension.aop.oplog.Oplog) || @within(cn.yifants.common.extension.aop.oplog.Oplogs)")
    public void classAnnotation() {
    }

    @Around("methodAnnotation() || classAnnotation()")
    public Object rounding(ProceedingJoinPoint joinPoint) throws Throwable {

        List<Oplog> annotations = new ArrayList<>();

        // 解析 Oplog 注解
        Oplog oplog = getMethodAnnotation(joinPoint, Oplog.class);
        if (oplog != null) {
            annotations.add(oplog);
        }
        annotations.addAll(getInheritClassAnnotation(joinPoint.getTarget().getClass(), Oplog.class));

        // 解析 Oplogs 注解
        Oplogs oplogs = getMethodAnnotation(joinPoint, Oplogs.class);
        if (oplogs != null) {
            annotations.addAll(Arrays.asList(oplogs.value()));
        }
        getInheritClassAnnotation(joinPoint.getTarget().getClass(), Oplogs.class).forEach(x -> {
            annotations.addAll(Arrays.asList(x.value()));
        });

        // 操作日志处理
        if (CollectionUtil.isNotEmpty(annotations)) {
            annotations.stream().distinct().forEach(x -> oplogHandle(x.value(), joinPoint));
        }

        Object[] args = joinPoint.getArgs();

        return joinPoint.proceed(args);
    }

    /**
     * 日志处理
     *
     * @param handle
     * @param joinPoint
     */
    private synchronized void oplogHandle(Class<? extends OplogHandle> handle, ProceedingJoinPoint joinPoint) {

        OplogHandle oplogHandle = applicationContext.getBean(handle, OplogHandle.class);

        // 获取当前请求客户端IP
        String ip = IpUtil.getIpAddress(httpServletRequest);

        oplogHandle.apply(OplogInfo.builder().ip(ip).build(),joinPoint);
    }
}

(3)使用方式

  • 在需要获取接口操作日志的方法或类,使用 @Oplog 或 @Oplogs 注解;
  • 实现 OplogHandle 接口​​​​​​,使用​ @Oplog(value = SysOplogHandleImpl.class) 即可;
    /**
     * @author chenyusheng
     * @create 2023/6/28 9:56
     * @description 系统操作日志处理 实现类
     */
    @Slf4j
    @Component("sysOplogHandleImpl")
    public class SysOplogHandleImpl implements OplogHandle {
    
        /**
         * 系统日志处理方法钩子
         *
         * @param oplogInfo 基本操作日志信息
         * @param joinPoint 切点
         */
        @Override
        public void apply(OplogInfo oplogInfo, ProceedingJoinPoint joinPoint) {
            
        }
    }


因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 69lv.com 版权所有 湘ICP备2023021910号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务