`

SpringBoot使用切面+注解实现对所有请求的日志记录到数据库中

 
阅读更多

业务场景:项目拆分微服务,恰巧鄙人负责几个基础的服务,各种对接其他服务。到后期运维,接各种锅:我调用你接口了,你那数据不对。我传递是这个参数,你那处理的有问题......。只好加上日志记录,业务场景就是:防止背锅!

 1.定义注解

package com.haier.hwork.qwrgqk.business.annotation;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    String value() default "";
    //1-增删改,2-查询,默认是1
    int type() default 1;
}

2.定义AOP

@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private TlOperationLogDao tlOperationLogDao;

  //扫描使用这个注解的方法
    @Pointcut("@annotation(com.haier.hwork.qwrgqk.business.annotation.OperationLog)")
    public void logPointCut() {}

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Date beginTime=new Date();
        String result=null;
        String status=null;
    //执行代码,都加try catch,即使出错也不能影响主进程
        try {
            Object obj = point.proceed();//放行请求的主进程并拿到返回值
            if(obj!=null) {
                result=JSONObject.toJSONString(obj);
            }
            status="success";
            return obj;
        } catch (Exception e) {
        //请求执行出错
            result=e.getMessage();
            status="error";
            throw e;
        } finally {
        //无论成功失败,都保存下日志
            saveLog(point, beginTime, new Date(), result, status);
        }
    }

  //保存日志
    private void saveLog(ProceedingJoinPoint joinPoint, Date beginTime, Date endTime, String result, String status) {
        TlOperationLog tlOperationLog=new TlOperationLog();
        try {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            OperationLog annotation = method.getAnnotation(OperationLog.class);
            int type=1;//注解类型
            if (annotation != null) {
                //注解上的描述
                tlOperationLog.setOperateModule(annotation.value());
          //注解类型
                tlOperationLog.setOperateType(String.valueOf(annotation.type()));
                type=annotation.type();
            }

      //记录入参
            if(joinPoint.getArgs()!=null) {
                try {
                    tlOperationLog.setParam(JSONObject.toJSONString(joinPoint.getArgs()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        //如果注解类型是1(增删改)或者是2(查询)报错,记录返回值,如果是查询正常就不记录,有可能返回值太多
            if(type==1 || "error".equals(status)) {
                tlOperationLog.setResult(result);
            }
            tlOperationLog.setStartTime(beginTime);//记录请求开始时间
            tlOperationLog.setEndTime(endTime);//记录请求结束时间
            tlOperationLog.setStatus(status);//记录执行状态

            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            if (request != null) {
                tlOperationLog.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));//记录请求头信息
                tlOperationLog.setUserCode(request.getHeader(Constant.HEADER_CURRENT_USER));//获取登录人,登录信息放在了header里
                if(request.getRequestURL()!=null) {//记录请求地址
                    tlOperationLog.setUrl(request.getRequestURL().toString());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    //启动一个线程,执行报错日志,防止影响主请求
        new Thread() {
            @Override
            public void run() {
                try {
            //保存数据到数据库
                    tlOperationLogDao.insertSelective(tlOperationLog);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

3.配置需要记录日志的方法

@PostMapping("/save")
@OperationLog("新增APP TOKEN管理")
public BaseResponse save() {
    return ResponseMsgUtil.success(tsSysAppTokenService.save());
}

凡是加上OperationLog注解的方法,都会记录日志,注解参数需要一个描述当前方法的字符串,会记录到数据库中。
另外还需要参数type,非必填,默认1,代表是增删改,type=2代表查询。
@OperationLog("新增APP TOKEN管理")
@OperationLog(value="查询管理客户接口", type=2)

 

分享到:
评论

相关推荐

    springBoot+aop+自定义注解+本地线程实现统一接口日志及接口响应时长

    核心原理:通过自定义注解实现每个接口的描述及所在模块还有接口的操作类型,通过拦截器及访问方法后的切面aop记录接口的总耗时,在接口请求前在本地线程记录请求的参数,接口请求后记录返回参数及记录请求日志 ...

    springboot+redis+shiro单点登录,统一异常处理,统一日志

    - 使用AOP(面向切面编程)实现全局日志记录,通过@Aspect注解定义一个切面类,拦截所有方法调用,记录方法的入参、出参、执行时间、异常信息等。 - 日志信息可以存储在数据库或日志服务器中,便于后期分析和排查...

    springboot+mybatis 分层设计

    SpringBoot可以通过依赖注入(DI)和面向切面编程(AOP)来管理Service层的bean。在这个例子中,Service层可以调用MyBatis的Mapper接口来执行数据库操作。 3. **数据访问层(DAO层)**:MyBatis作为数据访问层的...

    springboot+ssm+shiro

    7. 权限管理:定义角色和权限,使用Shiro的注解或拦截器实现对资源的访问控制。 8. 测试与优化:进行功能测试,确保登录、注销、权限控制等核心功能正常工作。根据实际需求调整配置,优化性能。 这个基础框架适用...

    基于springboot+mvc+freemarker+aop实现校友信息管理系统.zip

    通过`@Aspect`、`@Before`、`@After`等注解,我们可以定义切面、通知和切入点表达式,实现代码的解耦。 5. **项目结构** 一般来说,一个SpringBoot项目会包含以下主要目录: - `src/main/java`:存放Java源代码,...

    springboot连接数据库返回jsp项目

    通过在配置中启用嵌入式Tomcat服务器的JSP支持,并设置相应的静态资源路径,就可以在Spring Boot应用中使用JSP进行视图渲染。 总的来说,这个项目展示了SpringBoot在web开发中的强大能力,包括数据库连接、事务管理...

    SpringBoot无数据库模拟项目

    标签中的"spring"暗示了我们可能会用到Spring Framework的一些核心组件,如AOP(面向切面编程)来实现日志记录、事务管理等功能。同时,Spring的IoC(控制反转)容器将管理我们的bean生命周期,使得依赖注入变得简单...

    整合 springboot+mvc+mybatis(通用 mapper)+druid+jsp+bootstrap

    - **操作日志记录**:利用AOP(面向切面编程)记录用户的操作日志,便于后期分析和审计。 综上所述,这个项目提供了一个全面的后台管理系统模板,涵盖了常见的功能模块,并利用前沿的技术栈提升了开发效率和应用...

    基于springboot+mybatis学生管理系统.rar

    例如,使用Spring Security进行用户身份验证和授权,通过AOP(面向切面编程)处理全局异常,利用Log4j或Logback进行日志记录。 总之,“基于SpringBoot+MyBatis的学生管理系统”充分展示了这两种技术的融合优势,既...

    ssm+springboot+swagger+maven的接口项目

    在这个项目中,开发者可能使用了Spring的AOP(面向切面编程)来实现日志、权限控制等功能,而Spring MVC则用于处理HTTP请求,MyBatis则用来操作数据库。 2. **Spring Boot**:Spring Boot简化了Spring应用的初始...

    springboot+Mybatisplus实现多数据源

    SpringBoot结合MyBatisPlus提供了一种便捷的方式来实现多数据源的切换,使得开发者可以轻松应对复杂的数据库环境。下面将详细讲解如何使用SpringBoot和MyBatisPlus来实现多数据源的配置与切换。 首先,我们需要了解...

    springboot+ MyBatis +ssm+ Bootstrap+Mysql房屋租赁系统源码

    在这个项目中,虽然SpringBoot已经包含了SpringMVC,但依然提到了SSM,这可能意味着项目中还利用了Spring的一些特性,例如AOP(面向切面编程)进行权限控制,或者Spring的事务管理,确保数据操作的原子性和一致性。...

    springboot+redis+AOP 防止表单重复提交

    AOP是面向切面编程,允许开发者定义“切面”,这些切面可以封装跨越多个对象的行为,如日志记录、事务管理或,就像在这个场景中,防止表单重复提交。AOP的核心概念是“切点”(Pointcut)和“通知”(Advice)。切点...

    springboot数据库连接动态切换源代码

    - 使用Spring的AOP(面向切面编程)实现数据源的切换。创建一个`@Aspect`注解的切面类,定义一个切入点表达式匹配需要切换数据源的方法。 - 在`@Around`通知中,根据请求参数或安全上下文信息,设置`...

    springBoot+mybatis读写分离(AOP)

    AOP则是Spring框架的核心特性,用于在不修改原有代码的情况下,对特定行为(如日志记录、权限检查等)进行横切关注。 在Spring Boot项目中,我们可以通过AOP来实现读写分离。首先,我们需要定义两个数据源,一个...

    采用SpringBoot+Spring+Spring mvc+mybatis实现Flutter微校园APP的服务端程序-源码

    在本项目中,Spring框架用于管理对象的生命周期,进行依赖注入,使得各组件之间解耦合,同时通过AOP实现日志记录、事务管理等通用功能。 MyBatis是一个轻量级的持久层框架,它允许开发者将SQL语句直接写在XML配置...

    springboot切面添加日志功能实例详解

    本文将深入讲解如何利用Spring AOP(面向切面编程)来实现自定义的日志功能。 首先,我们需要创建一个新的Spring Boot项目。通过Spring Initializr或手动配置pom.xml文件,引入所需的依赖,确保Spring Web和Spring ...

    SpringBoot 接口访问频率限制(一)

    2. 编写一个切面类,实现注解的功能。这里我们可以使用Guava库的`RateLimiter`类来控制调用频率。 ```java @Aspect @Component public class RateLimitAspect { private final Map, RateLimiter> rateLimiters = ...

    基于springboot+web的学生用品采购系统源码数据库.zip

    MyBatis则是一个轻量级的持久层框架,它允许开发者用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 JSP(JavaServer Pages)是Java的...

Global site tag (gtag.js) - Google Analytics