最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中日志切面實現(xiàn)小結

 更新時間:2024年11月18日 10:06:33   作者:這個名字應該沒人用吧  
本文介紹了SpringBoot中日志切面實現(xiàn)小結,通過定義一個自定義注解和創(chuàng)建一個日志切面類,為方法添加日志記錄功能,感興趣的可以了解一下

在應用開發(fā)中,日志記錄對于監(jiān)控、調試和追蹤用戶行為至關重要。Spring Boot 雖然內置了強大的日志框架,但在某些情況下,我們可能需要更細粒度的日志管理。Spring AOP 提供了一種靈活的方式來實現(xiàn)方法級別的日志記錄,而無需侵入業(yè)務代碼。本文將介紹如何通過 Spring AOP 切面來實現(xiàn)這一功能。

什么是Spring AOP?

Spring AOP 是一個面向切面的編程(AOP)框架,它允許開發(fā)者將橫切關注點(如日志記錄、事務管理等)與業(yè)務邏輯分離。通過使用 Spring AOP,我們可以在不修改業(yè)務代碼的情況下,為應用程序添加日志記錄功能。

Spring AOP 詳細可以看這篇文章  Spring AOP入門

日志切面的設計

在我們的示例中,我們定義了一個 SysLog 注解,用于標記需要記錄日志的方法。接著,我們創(chuàng)建了一個日志切面 LogAspect,它會攔截所有帶有 SysLog 注解的方法,并記錄日志信息。

SysLog 注解

首先,我們定義了一個 SysLog 注解,它可以用來標記需要記錄日志的方法:

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

這個注解非常簡單,它只有一個 value 屬性,用于存儲日志的描述信息。

日志切面 LogAspect

接下來,我們創(chuàng)建了 LogAspect 切面類,它會攔截所有帶有 SysLog 注解的方法:

@Aspect
@Component
public class LogAspect {
    // 省略其他成員變量和方法

    @Around("@annotation(sysLog)")
    public Object logAround(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
        // 日志記錄邏輯
    }
}

在這個切面中,我們使用了 @Around 注解來定義一個環(huán)繞通知,它會在目標方法執(zhí)行前后記錄日志信息。

日志記錄的實現(xiàn)

在 LogAspect 切面類中,我們實現(xiàn)了 logAround 方法,它會在目標方法執(zhí)行前后記錄日志信息:

@Around("@annotation(sysLog)")
public Object logAround(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
    Log log = new Log();
    log.setTimestamp(new Date());
    log.setDescription(sysLog.value());
    log.setMethodName(joinPoint.getSignature().getName());
    log.setParameters(Arrays.toString(joinPoint.getArgs()));

    try {
        Object result = joinPoint.proceed();
        log.setLevel("INFO");
        log.setMessage("方法 " + joinPoint.getSignature().getName() + " 執(zhí)行成功。");
        return result;
    } catch (Exception e) {
        log.setLevel("ERROR");
        log.setMessage("方法 " + joinPoint.getSignature().getName() + " 執(zhí)行過程中發(fā)生異常。");
        log.setException(e.toString());
        throw e;
    } finally {
        logService.save(log);
    }
}

在這個環(huán)繞通知中,我們首先創(chuàng)建了一個 Log 對象,并設置了日志的基本信息,如時間戳、描述、方法名和參數(shù)。然后,我們執(zhí)行目標方法,并根據(jù)執(zhí)行結果記錄日志信息。如果目標方法執(zhí)行過程中發(fā)生異常,我們會記錄異常信息。

測試

完整代碼

Maven依賴

在 pom.xml 文件中添加依賴:

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

SQL腳本

創(chuàng)建日志表的 SQL 腳本:

DROP TABLE IF EXISTS `logs`;
CREATE TABLE `logs`  (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
  `level` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '日志級別',
  `timestamp` datetime NOT NULL COMMENT '時間戳',
  `message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '日志消息',
  `class_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '類名',
  `method_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '方法名',
  `parameters` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '參數(shù)',
  `user_identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用戶標識',
  `exception` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '異常信息',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '日志表' ROW_FORMAT = DYNAMIC;

日志實體類 Log

我們定義了一個 Log 實體類,用于存儲日志信息:

/**
 * 日志實體類
 *
 * @author 王聞薪
 */
@Data
@TableName("logs")
public class Log implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主鍵ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 描述
     */
    @TableField("description")
    private String description;

    /**
     * 日志級別
     */
    @TableField("level")
    private String level;

    /**
     * 時間戳
     */
    @TableField("timestamp")
    private Date timestamp;

    /**
     * 日志消息
     */
    @TableField("message")
    private String message;

    /**
     * 類名
     */
    @TableField("class_name")
    private String className;

    /**
     * 方法名
     */
    @TableField("method_name")
    private String methodName;


    /**
     * 參數(shù)
     */
    @TableField("parameters")
    private String parameters;

    /**
     * 用戶標識
     */
    @TableField("user_identifier")
    private String userIdentifier;

    /**
     * 異常信息
     */
    @TableField("exception")
    private String exception;

}

這個實體類映射到數(shù)據(jù)庫中的 logs 表,用于存儲日志的詳細信息。

切面代碼

日志切面類 LogAspect

package org.example.demo.aspectj;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.example.demo.annotation.SysLog;
import org.example.demo.entity.Log;
import org.example.demo.service.ILogService;
import org.example.demo.utils.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

/**
 * 日志切面類
 * 用于攔截標注有@SysLog注解的方法,并記錄日志信息。
 *
 * @author 王聞薪
 */
@Slf4j
@Aspect // 標記為切面類
@Component // 將此切面類交給Spring管理
public class LogAspect {

    @Autowired
    private ILogService logService;

    @Autowired
    private TokenService tokenService;

    /**
     * 環(huán)繞通知
     * 攔截帶有@SysLog注解的方法,并在方法執(zhí)行前后進行日志記錄。
     *
     * @param joinPoint 連接點對象,包含方法的調用信息。
     * @param sysLog 注解對象,包含日志描述信息。
     * @return 方法執(zhí)行結果。
     * @throws Throwable 可能拋出的異常。
     */
    @Around("@annotation(sysLog)")
    public Object logAround(ProceedingJoinPoint joinPoint, SysLog sysLog) throws Throwable {
        // 創(chuàng)建日志對象
        Log log = new Log();
        log.setLevel("INFO");
        log.setTimestamp(new Date());
        log.setUserIdentifier(getUserId().toString());
        log.setDescription(sysLog.value());
        // 記錄方法調用前的日志
        logBefore(joinPoint, log);

        try {
            // 繼續(xù)執(zhí)行目標方法
            Object result = joinPoint.proceed();

            // 記錄方法調用后的日志
            logAfter(joinPoint, result, log);
            log.setMessage("方法 " + joinPoint.getSignature().getName() + " 執(zhí)行成功。");

            return result;
        } catch (Exception e) {
            // 記錄異常日志
            logException(joinPoint, e, log);
            log.setLevel("ERROR");
            log.setMessage("方法 " + joinPoint.getSignature().getName() + " 執(zhí)行過程中發(fā)生異常。");
            throw e; // 重新拋出異常
        } finally {
            // 保存日志到數(shù)據(jù)庫
            logService.save(log);
        }
    }

    /**
     * 記錄方法調用前的日志信息。
     *
     * @param joinPoint 連接點對象,包含方法的調用信息。
     * @param log 日志對象,用于存儲日志信息。
     */
    private void logBefore(ProceedingJoinPoint joinPoint, Log log) {
        log.setClassName(joinPoint.getSignature().getDeclaringTypeName());
        log.setMethodName(joinPoint.getSignature().getName());
        log.setParameters(Arrays.toString(joinPoint.getArgs()));
        log.setTimestamp(new Date()); // 設置日志時間
    }

    /**
     * 記錄方法調用后的日志信息。
     *
     * @param joinPoint 連接點對象,包含方法的調用信息。
     * @param result 方法執(zhí)行結果。
     * @param log 日志對象,用于存儲日志信息。
     */
    private void logAfter(ProceedingJoinPoint joinPoint, Object result, Log log) {
        log.setMessage(log.getMessage() + result);
    }

    /**
     * 記錄方法執(zhí)行過程中的異常信息。
     *
     * @param joinPoint 連接點對象,包含方法的調用信息。
     * @param e 捕獲的異常對象。
     * @param log 日志對象,用于存儲日志信息。
     */
    private void logException(ProceedingJoinPoint joinPoint, Exception e, Log log) {
        log.setException(e.toString());
        log.setMessage(log.getMessage() + " 異常信息:" + e.getMessage());
    }

    /**
     * 獲取當前用戶ID。
     *
     * @return 用戶ID。
     */
    private Long getUserId() {
        return tokenService.getUserId();
    }
}

結論

通過使用 Spring AOP 和注解,我們可以靈活地為 Spring Boot 應用程序添加日志記錄功能,而無需修改業(yè)務邏輯代碼。這不僅提高了代碼的可維護性,還使得日志記錄變得更加方便和強大。

到此這篇關于SpringBoot中日志切面實現(xiàn)小結的文章就介紹到這了,更多相關SpringBoot 日志切面內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java實現(xiàn)把一個List集合拆分成多個的操作

    java實現(xiàn)把一個List集合拆分成多個的操作

    這篇文章主要介紹了java實現(xiàn)把一個List集合拆分成多個的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 使用Java和Redis實現(xiàn)高效的短信防轟炸方案

    使用Java和Redis實現(xiàn)高效的短信防轟炸方案

    在當今互聯(lián)網(wǎng)應用中,短信驗證碼已成為身份驗證的重要手段,然而,這也帶來了"短信轟炸"的安全風險?-?惡意用戶利用程序自動化發(fā)送大量短信請求,導致用戶被騷擾和企業(yè)短信成本激增,本文將詳細介紹如何使用Java和Redis實現(xiàn)高效的短信防轟炸解決方案,需要的朋友可以參考下
    2025-04-04
  • mybatis查詢字段為null設置為0的操作

    mybatis查詢字段為null設置為0的操作

    這篇文章主要介紹了mybatis查詢字段為null設置為0的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • SpringBoot ApplicationEvent之事件發(fā)布與監(jiān)聽機制詳解

    SpringBoot ApplicationEvent之事件發(fā)布與監(jiān)聽機制詳解

    本文將深入探討SpringBoot的事件機制,介紹其核心概念、實現(xiàn)方法及最佳實踐,幫助開發(fā)者構建更加靈活、可維護的應用架構,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java學習之異常處理的新特性詳解

    Java學習之異常處理的新特性詳解

    異常處理機制是Java很早時就搞出來的技術,但在實際應用中,我們發(fā)現(xiàn)這個異常處理也有一些不完善的地方,接下來主要給大家介紹一下Java異常處理的一些新特性,需要的朋友可以參考下
    2023-08-08
  • 解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題

    解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題

    這篇文章主要介紹了解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • IntelliJ IDEA像Eclipse一樣打開多個項目的圖文教程

    IntelliJ IDEA像Eclipse一樣打開多個項目的圖文教程

    這篇文章主要介紹了IntelliJ IDEA像Eclipse一樣打開多個項目的方法圖文教程講解,需要的朋友可以參考下
    2018-03-03
  • Java OOM原因以及解決方案

    Java OOM原因以及解決方案

    這篇文章主要介紹了Java OOM原因以及解決方案,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-09-09
  • Java通過jersey實現(xiàn)客戶端圖片上傳示例

    Java通過jersey實現(xiàn)客戶端圖片上傳示例

    本篇文章主要介紹了Java通過jersey實現(xiàn)客戶端圖片上傳示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • MyBatis如何調用存儲過程與存儲函數(shù)

    MyBatis如何調用存儲過程與存儲函數(shù)

    這篇文章主要介紹了MyBatis如何調用存儲過程與存儲函數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評論

西贡区| 广宁县| 湖口县| 青神县| 集贤县| 铜山县| 内乡县| 准格尔旗| 凤阳县| 香河县| 瑞昌市| 永新县| 锦州市| 潜江市| 罗甸县| 醴陵市| 和龙市| 长海县| 饶阳县| 台中市| 茂名市| 德庆县| 子长县| 芜湖市| 汽车| 宜都市| 梁山县| 景洪市| 武冈市| 镇江市| 增城市| 乐平市| 琼结县| 北川| 旺苍县| 乌拉特前旗| 宜阳县| 浦东新区| 彩票| 诸城市| 罗源县|