java springboot架构 自定义注解保存项目业务日志,使用线程池保存到数据库

这篇具有很好参考价值的文章主要介绍了java springboot架构 自定义注解保存项目业务日志,使用线程池保存到数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1:pom.xml依赖

2:注解类样例

3:枚举类

4:具体处理方法类

5:线程池类文章来源地址https://www.toymoban.com/news/detail-550131.html


1:pom.xml依赖


<!-- SpringBoot 拦截器 -->
<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2:注解类样例

package com.hgfr.gfs.logconfig.controller;

import java.lang.annotation.*;

/**
 * 自定义操作日志记录注解
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BusinessLog {
    /**
     * 操作人名称
     */
    public String OperationName() default "";

}

3:枚举类

package com.hgfr.gfs.logconfig.controller;

public enum BusinessType {
    ADD("新增"),
    UPDATE("修改"),
    OTHER("其他"),
    EXPORT_IN("导入"),
    EXPORT_OUT("导出"),
    DELETE("删除");

    private String value;

    BusinessType(String s) {
        this.value =s;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

4:具体处理方法类

package com.hgfr.gfs.logconfig.controller;

import com.hgfr.gfs.log.entity.GsOperateLog;
import com.hgfr.gfs.log.service.IGsOperateLogService;
import lombok.extern.slf4j.Slf4j;
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.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.TimerTask;

/**
 * 注解解析
 */
@Aspect
@Component
@Slf4j
public class MyLogAspect {

    //注解设置到类
    @Pointcut("@annotation(com.hgfr.gfs.logconfig.controller.BusinessLog)")
    public void logPointCut() {

    }

    @Autowired
    IGsOperateLogService iGsOperateLogService;
    /**
     * 处理完请求前执行
     *
     * @param joinPoint 切点
     */
    @Before(value = "logPointCut()")
    public void before(JoinPoint joinPoint) {
        log.info("before");
    }

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
        log.info("doAfterReturning");
        handleLog(joinPoint, null, jsonResult);
    }

    /**
     * 拦截异常操作
     *
     * @param joinPoint 切点
     * @param e         异常
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
        log.info("doAfterThrowing");
        handleLog(joinPoint, e, null);
    }

    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
        try {
            // 获得注解
            BusinessLog controllerLog = getAnnotationLog(joinPoint);
            if (Objects.isNull(controllerLog)) {
                return;
            }
            // 数据库日志
            GsOperateLog sysOperationLog = new GsOperateLog();
            // 处理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, sysOperationLog);
            // 保存数据库
//            iGsOperateLogService.save(sysOperationLog);
            ThreadPoolFactory.threadPoolExecutor.execute(saveTest(sysOperationLog));
        } catch (Exception exp) {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }
    public TimerTask saveTest(GsOperateLog sysOperationLog) {
        return new TimerTask() {
            @Override
            public void run() {
                // 耗时操作
                try {
                    // 保存数据库
                    iGsOperateLogService.save(sysOperationLog);
                } catch (Exception e) {
                    log.error("SleepingTest:" + e.toString());
                }
            }
        };
    }

    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     *
     * @param businessLog     日志
     * @param sysOperationLog 操作日志
     * @throws Exception
     */
    public void getControllerMethodDescription(JoinPoint joinPoint, BusinessLog businessLog, GsOperateLog sysOperationLog) throws Exception {
        sysOperationLog.setOperateType(businessLog.OperationType().getValue());
        sysOperationLog.setRequestType(businessLog.OperationDetail());
        String methodName = businessLog.MethodName();
        sysOperationLog.setUserName(methodName);

    }

    /**
     * 是否存在注解,如果存在就获取
     */
    private BusinessLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(BusinessLog.class);
        }
        return null;
    }

    /**
     * 获取参数Map集合
     * @param joinPoint
     * @return
     */
    Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
            param.put(paramNames[i], paramValues[i]);
        }
        return param;
    }

    /**
     * 处理完请求中执行
     * @param point 切点
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) {
        log.info("around");
        //获取方法名称
        Signature methodName = point.getSignature();
        //日志输出
        log.info(methodName + "进来了");
        Long l1 = System.currentTimeMillis();
        Object obj = null;
        try {
            obj = point.proceed(point.getArgs());
        } catch (Throwable e) {
            e.printStackTrace();
        }
        log.info(methodName + "bye" + "\t耗時 " + (System.currentTimeMillis() - l1));
        //记录一个耗时时间,将证明日志通知
        return obj;
    }

}

5:线程池类

package com.hgfr.gfs.logconfig.controller;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadPoolFactory {

    /**
     * 线程池信息: 核心线程数量5,最大数量10,队列大小20,超出核心线程数量的线程存活时间:30秒, 指定拒绝策略的
     */
    public static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(20), new RejectedExecutionHandler() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            log.error("有任务被拒绝执行了");
        }
    });

}

到了这里,关于java springboot架构 自定义注解保存项目业务日志,使用线程池保存到数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot项目中添加自定义日志

    或 application.yml文件中的配置 对上述的配置进行说明:

    2024年02月17日
    浏览(29)
  • [Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例

    下面的案例中只是做一个简单的了解,不做深入理解啦 目录 一.使用Logback写日志 二.类加载器 三.XML 四.XML编写规定:DTD与schema 五.XML解析 六.XPath 七.单元测试 七.Assert(断言):检验方法结果 八.使用before与after注解备份与还原数据 九.注解 十.自定义注解 十一.注解案例:用注

    2024年02月04日
    浏览(44)
  • java的springboot框架中使用logback日志框架使用RabbitHandler注解为什么获取不到消费的traceId信息?

    当使用 Logback 日志框架和 RabbitMQ 的 @RabbitHandler 注解时,如果无法获取消费的 traceId 信息,可能是因为在处理 RabbitMQ 消息时,没有正确地将 traceId 传递到日志中。 为了将 traceId 传递到日志中,你可以利用 MDC(Mapped Diagnostic Context)机制。MDC 是一个线程绑定的上下文容器,允许

    2024年02月09日
    浏览(30)
  • 【操作日志】如何在一个SpringBoot+Mybatis的项目中设计一个自定义ChangeLog记录?

    设计一个业务改动信息时的自定义记录,例如新增、修改、删除数据等。并且记录的规则可以通过配置的方式控制。大家需要根据各自业务场景参考,欢迎讨论。伪代码如下: 实体类:   DAO层:     自定义注解:   Http接口请求参数:   Http接口:   SQL拦截器:   Spring切面

    2024年02月06日
    浏览(28)
  • 【Java】SpringBoot集成P6spy,实现自定义SQL日志打印

    在项目中对数据库中进行操作调试的时候,最重要的一个功能就是 SQL打印 。 如果使用Mybatis-plus的话,他会自带一个SQL打印的功能。虽然它可以打印,但我觉得还不够优雅,因为包含着很多我们不需要的信息,所以这篇文章实现一下在代码中优雅的打印SQL。 P6Spy 是针对数据库

    2024年02月16日
    浏览(40)
  • Springboot整合AOP实现日志的保存

    1.定义注解 2.编写切面的实现 3.测试

    2024年02月09日
    浏览(36)
  • Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志

    今天主要说说如何通过自定义注解的方式,在 Spring Boot 中来实现 AOP 切面统一打印出入参日志。小伙伴们可以收藏一波。 废话不多说,进入正题! 在看看实现方法之前,我们先看下切面日志输出效果咋样: 从上图中可以看到,每个对于每个请求,开始与结束一目了然,并且

    2024年02月08日
    浏览(35)
  • SpringBoot的日志信息及Lombok的常用注解

    日志是我们程序重要组成部分,它是程序在运行过程当中输出的一些提示或异常信息,我们可以通过日志来观察程序执行的情况,如果程序出现 Bug,我们可以根据日志去发现和排查程序的 Bug。 SpringBoot 项目在启动的时候,就会有默认的日志输出,如下图所示: 之所以会有上

    2024年02月12日
    浏览(26)
  • Day920.结构化日志&业务审计日志 -SpringBoot与K8s云原生微服务实践

    Hi,我是 阿昌 ,今天学习记录的是关于 结构化日志业务审计日志 的内容。 结构化日志 (Structured Logging)是一种将日志信息组织为结构化数据的技术。 传统的日志通常是一些文本信息,比如一行记录一个错误或者事件,这些信息往往是自由格式的。 相比之下,结构化日志则

    2023年04月09日
    浏览(26)
  • springboot 自定义注解

    1、引入maven依赖(版本太低也会导致不生效) 2、创建注解接口(javax.validation版本是2.0.0的,自行选择,太低也不行) 3、可以创建全局异常来捕获(Result可以自己定义) 4、统一返回结果类 5、场景使用

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包