在Spring Boot中,利用AOP(Aspect-Oriented Programming)实现操作日志记录。

在Spring Boot中,利用AOP(Aspect-Oriented Programming)结合自定义注解,可以优雅地实现操作日志记录。这种方式不仅解耦了业务逻辑与日志记录功能,还能让代码更简洁、可维护性更高。

以下是实现步骤:

1. 项目依赖

在Spring Boot项目中,确保以下依赖已存在(默认spring-boot-starter-aopspring-boot-starter引入):

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

2. 自定义注解

首先创建一个注解,用于标记需要记录操作日志的方法。

package com.example.aspect;

import java.lang.annotation.*;

@Documented
@Target(ElementType.METHOD) // 作用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface LogOperation {

    String value() default ""; // 描述信息
}

3. 创建 AOP 切面

通过 AOP 切面拦截带有 @LogOperation 注解的方法,并实现日志记录。

package com.example.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
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 java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
public class LogAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    // 定义切点:匹配带有 @LogOperation 注解的方法
    @Pointcut("@annotation(com.example.aspect.LogOperation)")
    public void logPointcut() {
    }

    // 环绕通知:在方法执行前后做增强
    @Around("logPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        // 获取方法信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogOperation logOperation = method.getAnnotation(LogOperation.class);

        // 获取方法参数
        Object[] args = joinPoint.getArgs();

        // 日志内容
        String operationDesc = logOperation.value();
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();

        logger.info("开始执行操作: {}", operationDesc);
        logger.info("类名: {}, 方法: {}", className, methodName);
        logger.info("方法参数: {}", Arrays.toString(args));

        Object result;
        try {
            result = joinPoint.proceed(); // 执行目标方法
            logger.info("操作成功: {}", operationDesc);
        } catch (Exception e) {
            logger.error("操作失败: {}, 异常信息: {}", operationDesc, e.getMessage(), e);
            throw e;
        } finally {
            long endTime = System.currentTimeMillis();
            logger.info("操作耗时: {}ms", (endTime - startTime));
        }

        return result;
    }
}

4. 示例:应用注解

在控制器或服务方法中使用 @LogOperation 注解。

控制器示例

package com.example.controller;

import com.example.aspect.LogOperation;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ExampleController {

    @GetMapping("/example")
    @LogOperation("查询示例数据")
    public String getExample(@RequestParam String name) {
        return "Hello, " + name;
    }

    @PostMapping("/example")
    @LogOperation("保存示例数据")
    public String saveExample(@RequestBody String data) {
        // 模拟保存逻辑
        return "Data saved: " + data;
    }
}

服务层示例

package com.example.service;

import com.example.aspect.LogOperation;
import org.springframework.stereotype.Service;

@Service
public class ExampleService {

    @LogOperation("执行复杂业务逻辑")
    public String complexOperation(String input) {
        // 模拟复杂逻辑
        return "Processed: " + input;
    }
}

5. 日志输出示例

访问 /api/example?name=John 时,日志将输出如下内容:

INFO  - 开始执行操作: 查询示例数据
INFO  - 类名: com.example.controller.ExampleController, 方法: getExample
INFO  - 方法参数: [John]
INFO  - 操作成功: 查询示例数据
INFO  - 操作耗时: 12ms

6. 进阶功能

(1) 保存日志到数据库

可以在 AOP 中直接将日志信息持久化到数据库,例如通过 LogRepository 保存日志:

@Autowired
private LogRepository logRepository;

logRepository.save(new LogEntity(operationDesc, className, methodName, args, timestamp));

(2) 动态获取用户信息

结合 Spring Security 或 Token 解析,获取当前用户信息:

String username = SecurityContextHolder.getContext().getAuthentication().getName();
logger.info("操作用户: {}", username);

(3) 日志级别控制

根据不同操作,选择合适的日志级别(INFO、DEBUG、ERROR 等)。

(4) 异步记录

使用 @Async 注解将日志记录操作改为异步,提高接口响应速度。

7. 完整性测试

对带有 @LogOperation 注解的方法进行测试,验证日志功能是否正常记录,并检查以下场景:

  • 方法执行成功。
  • 方法抛出异常。
  • 方法参数为空。

通过以上实现,利用 AOP 和自定义注解,不仅能优雅地记录操作日志,还能保持业务逻辑的简洁性,为后续功能扩展打下基础。

发布者:myrgd,转载请注明出处:https://www.object-c.cn/4434

Like (0)
Previous 2024年11月23日 下午1:53
Next 2024年11月23日 下午2:03

相关推荐

  • 在 Jupyter Notebook 中使用 Markdown 的相关技巧

    在 Jupyter Notebook 中使用 Markdown 是一种常见的方式来撰写文档和注释,增强数据分析和报告的可读性。Markdown 在 Jupyter Notebook 中不仅支持标准的文本格式化功能,还提供了许多扩展功能,比如数学公式、表格、代码块等。以下是一些常用的 Markdown 技巧,可以帮助你提升 Jupyter Notebook 中…

    2024年11月27日
    7300
  • 如何使用uni-app-qrcode插件生成二维码?

    以下是使用uni-app-qrcode插件生成二维码的详细步骤: 安装插件 或者使用yarn进行安装: 引入插件 使用插件生成二维码 上述代码中,首先定义了要编码到二维码中的内容content和生成二维码的配置选项options,然后通过this.$refs.qrcodeCanvas获取页面中的canvas元素,最后调用QRCode.make方法生成二维码。…

    5天前
    1400
  • 云服务器的 宝塔面板 中配置 PHP 支持 WebP 格式的图片

    在云服务器的 宝塔面板 中配置 PHP 支持 WebP 格式的图片,主要是通过安装或启用 GD 库或者 ImageMagick 来实现 WebP 图片的处理支持。下面是一步步的操作方法:1. 确保服务器已经安装 WebP 扩展WebP 格式的支持需要 PHP 依赖于 GD 库或 ImageMagick 库。如果你使用的是 PHP 7.0 及以上版本,通常 G…

    2024年11月29日
    4200
  • Flutter 在 PC 端多窗口支持方面的进展备受关注的功能,已在 Ubuntu/Canonical 展示

    Flutter 在 PC 端多窗口支持方面的进展是一个备受关注的功能,它的目标是进一步提升 Flutter 的跨平台能力。最近,Flutter 团队与 Canonical 合作,在 Ubuntu 平台上展示了多窗口功能的新成果。这一进展对开发者和终端用户来说都有重要意义,以下是相关细节分析: 展示细节多窗口功能亮相Flutter 的多窗口支持在 Ubuntu…

    2024年12月2日
    7000
  • 解决 Vue 3 应用部署到 GitHub Pages 后,遇到 404 错误问题

    在将 Vue 3 应用部署到 GitHub Pages 后,遇到 404 错误通常是由于 GitHub Pages 处理路由时的问题。Vue 3 使用 Vue Router 来管理前端路由,而 GitHub Pages 本身是静态托管服务,不支持处理 SPA(单页面应用)的客户端路由。因此,当你直接访问某个页面 URL(比如 https://youruser…

    2024年11月29日
    3100
  • 使用 Webpack 5 优化构建减少生成文件的体积提升前端性能

    在使用 Webpack 5 时,优化构建以减少生成文件的体积是提升前端性能的重要一步。以下是一些常见的优化方法和策略: 1. 开启生产模式 确保构建时使用生产模式,Webpack 会自动应用多种优化(如代码压缩、Tree Shaking 等): 或在配置文件中明确设置: 2. 启用 Tree Shaking Tree Shaking 是 Webpack 内置…

    2024年12月3日
    3300
  • Jeewx-Api 1.3.1 发布:更简易的微信小程序开发 API 降低了开发成本

    Jeewx-Api 1.3.1 发布:更简易的微信小程序开发 API Jeewx-Api 是一款开源的微信开发 SDK,支持微信公众号、小程序、企业微信等全场景开发。1.3.1 版本针对小程序功能做了全面优化,为开发者提供了更简洁易用的 API,降低了开发成本。 1. 新版本亮点 支持微信小程序功能 更简洁的 API 支持企业微信与公众号 2. Jeewx-…

    2024年12月3日
    3000
  • 博客网站的链接添加nofollow的好处

    在博客中为链接添加 nofollow 属性可以在以下几个方面带来好处: 1. 防止权重流失作用:为外部链接添加 nofollow 标签可以阻止搜索引擎将页面权重(PageRank)传递给目标页面,从而保留网站自身的 SEO 权重。适用场景:指向不可靠或低质量内容的链接。赞助商链接或付费推广链接。 2. 避免搜索引擎惩罚作用:搜索引擎(如 Google)要求对…

    2024年11月28日
    2000
  • 使用 Python Selenium 控制 Chrome 浏览器 进行自动化操作

    使用 Python Selenium 控制 Chrome 浏览器 进行自动化操作是 Web 自动化测试和爬虫的常用方法之一。以下是一个完整的入门教程,包括如何安装、配置以及一些示例代码。 1. 安装所需环境 1.1 安装 Selenium 使用 pip 安装 Selenium: 1.2 下载 ChromeDriver 1.3 配置 ChromeDriver …

    2024年11月25日
    16000
  • 微信小程序中,通过Node.js连接本地 MySQL 实现数据的增删改查

    在微信小程序中,通过Node.js连接本地 MySQL 实现数据的增删改查的过程,可以分为以下几个步骤: 1. 准备工作 必要工具: 2. 搭建 Node.js 后端服务 安装依赖 在 Node.js 项目中,使用 npm init 初始化项目,并安装以下依赖: express: 用于搭建 Web 服务。 mysql: 用于连接和操作 MySQL 数据库。 …

    2024年12月9日
    3100
  • 在 Nuxt.js 应用中,webpack 的 compile 事件钩子构建过程

    在 Nuxt.js 应用中,webpack 的 compile 事件钩子通常用于在构建过程中处理或监听 Webpack 编译的状态。webpack 是 Nuxt.js 中的核心构建工具之一,而 Nuxt.js 本身是基于 Webpack 配置的,允许你通过扩展 Webpack 配置来进行自定义。要使用 webpack 的 compile 事件钩子,首先你需要…

    2024年11月29日
    2600
  • 在 Ant Design ProTable 中,如何设置不分页,依然显示分页信息,前端分页不触发

    在 Ant Design ProTable 中,默认情况下,分页是与数据请求(request)相关联的。也就是说,每当分页切换时,request 会被触发,重新请求新的数据。如果你希望在禁用分页的同时,依然显示分页控件,并且不触发 request 请求,可以通过以下方法进行配置。解决方案要在 Ant Design ProTable 中禁用分页的同时保留分页信…

    2024年11月29日
    13900
  • python反爬-图像验证码与滑块验证码的跳过反selenium检测,动态ip等问题

    针对反爬措施,Python可以使用以下策略来跳过图像验证码与滑块验证码、反检测Selenium,以及通过动态IP规避限制。这是一个分步说明: 1. 图像验证码的跳过与破解1.1 图像验证码处理对于简单的图像验证码,可以使用 OCR 技术直接识别验证码内容。常用库包括:Tesseract-OCR: 一款开源 OCR 工具。Pytesseract: Tesser…

    2024年11月28日
    2600
  • 在 uni-app 小程序中,使用 uni.getLocation 获取用户位置信息等

    在 uni-app 小程序 中,使用 uni.getLocation 获取用户位置后,可以通过 腾讯地图 API 将经纬度转化为详细的地址信息(如省、市、区、街道等)。以下是完整的操作流程: 1. 前置准备:开通腾讯地图 API 服务注册腾讯位置服务账号:登录 腾讯位置服务官网。创建项目并获取 Key:进入 控制台,创建新应用,选择 小程序。获取生成的 ke…

    2024年11月26日
    19800
  • uniapp基于vue3,element plus组件库以及axios通讯开发

    在 uniapp 前端开发中,使用 Vue3、Element Plus 组件库和 Axios 进行通讯是一种常见的组合。下面是一个简单的步骤和实践指南,帮助你更好地使用这些工具进行开发。1. 安装和配置 Vue3 和 Element Plus首先,确保你已经安装了 uniapp 项目,并且设置好相关依赖。在项目中,安装 Element Plus 组件库以便在…

    2024年11月27日
    11200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信