一张思维导图带你学会SpringBoot使用AOP实现日志管理功能

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 一张思维导图带你学会SpringBoot使用AOP实现日志管理功能

思维导图



🌟AOP介绍


基本概念:在不改变原有功能的逻辑,增加新的功能。

应用场景

  • 权限控制
  • 日志处理
  • 事务控制


下面以对产品数据增删改查功能,进行日志管理功能为例,对AOP中的核心概念作出介绍,请参考下表

概念 解析 对应日志管理功能
核心关注点 业务逻辑的主要功能,应用程序主要关注的部分 产品数据的增删改查
横切关注点 与核心关注点相关但不属于核心关注点的功能,在系统的多个模块或组件中散布 记录产品操作的日志
通知 在特定切入点执行时要执行的代码,实现横切关注点的具体逻辑。可以在目标方法执行之前、之后或抛出异常时执行 执行记录日志的代码
连接点 可以插入通知的特定点,通常是方法执行的位置 产品表操作的方法
切入点 通过表达式或规则定义的连接点的集合。确定了哪些连接点与通知关联起来 选择所有的插入、更新或删除操作的连接点集合
切面 横切关注点和通知的组合,将通知应用到切入点匹配的连接点上 包含记录日志的通知和定义切入点的规则
目标 被通知的对象或类,即应用程序中执行具体操作的对象或方法 对产品数据作出操作的对象或方法
织入 将切面应用到目标对象上,创建新的代理对象的过程。可以在编译时、加载时或运行时进行 将日志管理切面应用到产品表操作的目标对象上,以记录日志


🌟具体实现步骤


数据准备


创建产品表、以及日志表,并向产品表添加相关数据。

CREATE TABLE `product`  (
  `id` int(11) NOT NULL,
  `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `price` decimal(10, 2) NULL DEFAULT NULL,
  `stock` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
-- ----------------------------
-- Records of product
-- ----------------------------
INSERT INTO `product` VALUES (1, '苹果13', 10.99, 50);
INSERT INTO `product` VALUES (2, '小米10', 19.99, 99);
INSERT INTO `product` VALUES (3, '华为mate20', 5.99, 19);
CREATE TABLE `log`  (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `operation` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `operate_time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;


引入相关依赖


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>


创建实体类


Product类

public class Product implements Serializable {
    private Integer id;
    private String name;
    private BigDecimal price;
    private Integer stock;
}


Log类

public class Log implements Serializable {
    private Integer id;
    private String operation;
    private String data;
    private Timestamp operateTime;
}


自定义注解@LogTip


自定义注解,用于标记记录日志的方法。

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogTip {
    String value() default "";
}


定义切面类


切面类由切点PointCut+通知Advice共同构成。有关于通知的类型以及解释,可以查看思维导图中的通知节点。有关于JoinPoint的API见下表

API 描述
getSignature() 获取连接点的签名,返回一个MethodSignature对象
getArgs() 获取连接点方法的参数数组
getTarget() 获取目标对象
getThis() 获取当前代理对象
toShortString() 生成连接点的简短描述
toLongString() 生成连接点的详细描述
getStaticPart() 获取静态连接点部分
getKind() 获取连接点的类型
getSourceLocation() 获取连接点所在位置的源代码位置
@Component
@Aspect
public class LogAspect {
    @Autowired
    private LogMapper logMapper;
    @Pointcut("@annotation(com.shoanjen.redis.annotation.LogTip)")
    public void pointCut(){}
    @AfterReturning("pointCut()")
    public void getLogInfo(JoinPoint point) throws Throwable {
        // 获取方法参数列表
        Object[] args = point.getArgs();
        //获取自定义注解上的描述信息
        MethodSignature methodSignature= (MethodSignature) point.getSignature();
        Method method=methodSignature.getMethod();
        LogTip annotation=method.getAnnotation(LogTip.class);
        String desc=annotation.value();
        // 获取操作的数据
        String data = Arrays.toString(args);
        // 记录日志
        saveLog(desc, data);
    }
    private void saveLog(String desc, String data) {
        Log log = new Log();
        log.setOperation(desc);
        log.setData(data);
        log.setOperateTime(new Timestamp(System.currentTimeMillis()));
        logMapper.save(log);
    }
}


LogMapper


public interface LogMapper {
    void save(Log log);
}


<insert id="save" parameterType="com.shoanjen.redis.model.Log" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
       INSERT INTO log(operation, data, operate_time) VALUES (#{operation}, #{data}, #{operateTime});
</insert>


ProductController


这里以上一篇文章一张思维导图带你学会使用SpringBoot异步任务实现下单校验库存中的产品下单功能为例子,对其记录日志。

@RestController
@RequestMapping("/api/v1/product")
public class ProductController {
    @Autowired
    private ProductService productService;
    @Autowired
    private ValidateTask validateTask;
    @LogTip("产品下单")
    @RequestMapping("order")
    public JsonData order(@RequestParam int productId,@RequestParam int quantity) throws ExecutionException, InterruptedException {
        Future<Boolean> validateResult=validateTask.validateStock(productId,quantity);
        System.out.println(validateResult.get());
        Boolean flag=false;
        //判断异步任务是否完成
        if (validateResult.isDone()){
            try {
                flag=validateResult.get();
            } catch (Exception e) {
                flag=false;
            }
        }
        if (flag){
            return JsonData.buildSuccess("下单成功");
        }else {
            return JsonData.buildError("下单失败,库存不足");
        }
    }
}


🌟最终测试


接口请求测试



1f9be352187d98f22c0c1953738d75f4_2caece314df04a99988a8b95ca699739.png


日志表查看



🌟写在最后


有关于SpringBoot使用AOP实现日志管理功能到此就结束了。感谢大家的阅读,希望大家在评论区对此部分内容散发讨论,便于学到更多的知识。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
8天前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
43 5
|
1月前
|
XML Java 数据格式
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
85 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
|
16天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
32 1
|
1月前
|
Java Maven Spring
SpringBoot日志整合
SpringBoot日志整合
19 2
|
1月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
127 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
1月前
|
SQL XML 监控
SpringBoot框架日志详解
本文详细介绍了日志系统的重要性及其在不同环境下的配置方法。日志用于记录系统运行时的问题,确保服务的可靠性。文章解释了各种日志级别(如 info、warn、error 等)的作用,并介绍了常用的日志框架如 SLF4J 和 Logback。此外,还说明了如何在 SpringBoot 中配置日志输出路径及日志级别,包括控制台输出与文件输出的具体设置方法。通过这些配置,开发者能够更好地管理和调试应用程序。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
143 1
|
17天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
95 62
|
15天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
34 2
|
18天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。