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

SpringBoot實(shí)現(xiàn)操作日志記錄的完整指南

 更新時(shí)間:2025年08月31日 09:24:58   作者:現(xiàn)在沒有牛仔了  
在SpringBoot項(xiàng)目中,若將日志記錄代碼散亂地嵌入到每個(gè)業(yè)務(wù)方法的try-catch塊中,會(huì)導(dǎo)致代碼重復(fù)嚴(yán)重,不利于維護(hù),本文將探討如何利用SpringBoot面向切面編程(AOP) 來優(yōu)雅地解決這一難題,希望對(duì)大家有所幫助

引言

在項(xiàng)目中,無論是在開發(fā)環(huán)境還是生產(chǎn)環(huán)境,如果系統(tǒng)出現(xiàn)故障,迎面而來的第一個(gè)問題往往是: “這個(gè)操作是誰在什么時(shí)候執(zhí)行的?具體做了什么改動(dòng)?” 如果系統(tǒng)對(duì)此一無所知,排查工作就如同大海撈針。

操作日志記錄正是為了解決這一問題而生。它是一個(gè)系統(tǒng)性的、用于追蹤用戶行為、厘清操作責(zé)任以及復(fù)現(xiàn)歷史流程的核心功能。它是系統(tǒng)的“黑匣子”,也是開發(fā)者的“記事本”。 在SpringBoot項(xiàng)目中,若將日志記錄代碼散亂地嵌入到每個(gè)業(yè)務(wù)方法的try-catch塊中,會(huì)導(dǎo)致代碼重復(fù)嚴(yán)重、核心業(yè)務(wù)邏輯被污染、不利于維護(hù)。

本文將探討如何利用SpringBoot面向切面編程(AOP) 來優(yōu)雅地解決這一難題。

一、環(huán)境準(zhǔn)備與項(xiàng)目搭建

1. 創(chuàng)建一個(gè)標(biāo)準(zhǔn)的SpringBoot項(xiàng)目

我使用的是SpringBoot3.5.5+JDK17

2. 引入核心依賴

  • mysql-connector-j(數(shù)據(jù)庫驅(qū)動(dòng))
  • mybatis-plus-spring-boot3-starter(數(shù)據(jù)持久化框架)
  • spring-boot-starter-aop(AOP核心)
  • aspectjweaver(面向切面工具)
  • spring-boot-starter-web(Web項(xiàng)目)
  • fastjson2(阿里json解析器)

二、實(shí)現(xiàn)步驟

1. 創(chuàng)建日志實(shí)體類(OperateLog)

@Data
public class OperateLog {
    private Long id; //主鍵
    private Long userId; //操作人id
    private Date createTime; //創(chuàng)建時(shí)間
    private String description; //請(qǐng)求描述
    private String method; //請(qǐng)求方法 如:post、get
    private String ip; //操作人ip
    private String param; //請(qǐng)求參數(shù):json格式
    private String result; //請(qǐng)求結(jié)果:json格式
    private Integer success; //操作是否成功
    private String errorMsg; //錯(cuò)誤信息
}

2. 創(chuàng)建操作日志記錄表(operate_log)

create table operate_log(
	id BIGINT PRIMARY key AUTO_INCREMENT COMMENT '主鍵',
	user_id BIGINT DEFAULT 100 COMMENT '操作人id',
	create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
	description VARCHAR(200) COMMENT '請(qǐng)求描述',
	method VARCHAR(20) COMMENT '請(qǐng)求方法 如:post、get',
	ip VARCHAR(32) COMMENT '操作人ip',
	param VARCHAR(2000) COMMENT '請(qǐng)求參數(shù):json格式',
	result VARCHAR(2000) COMMENT '請(qǐng)求結(jié)果:json格式',
	success TINYINT DEFAULT 0 COMMENT '操作是否成功:1是、0否',
	error_msg VARCHAR(2000) COMMENT '錯(cuò)誤消息'
) COMMENT '操作日志記錄表';

3. 創(chuàng)建添加日志的相關(guān)代碼

//mapper接口
public interface OperateLogMapper extends BaseMapper<OperateLog> {}

//service接口
public interface OperateLogService extends IService<OperateLog> {}

//service實(shí)現(xiàn)類
@Service
public class OperateLogServiceImpl extends ServiceImpl<OperateLogMapper, OperateLog> implements OperateLogService {}

4. 創(chuàng)建自定義注解(@Log)

在注解類中,指定其可以對(duì)方法進(jìn)行修飾,并設(shè)置運(yùn)行時(shí)保留策略

@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    /**
     * 請(qǐng)求描述
     */
    String title() default "";
}

5. 創(chuàng)建切面類(LogAspect)- 核心

在切面類中,創(chuàng)建前置通知和后置通知,并指定被@Log注解修飾的方法為切點(diǎn),實(shí)現(xiàn)對(duì)目標(biāo)方法的“增強(qiáng)”。

@Aspect
@Component
public class LogAspect {
    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    @Autowired
    private OperateLogService logService;

    private final ExecutorService executor = Executors.newSingleThreadExecutor();

    /**
     * 請(qǐng)求前執(zhí)行
     * @param aspLog
     */
    @Before(value = "@annotation(aspLog)")
    public void doBefore(Log aspLog){
        log.info("請(qǐng)求日志記錄start");
    }

    /**
     * 請(qǐng)求后執(zhí)行
     * @param aspLog
     * @param result
     */
    @AfterReturning(pointcut = "@annotation(aspLog)",returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Log aspLog, Object result){
        handleLog(joinPoint,aspLog,null,result);
    }

    /**
     * 請(qǐng)求異常執(zhí)行
     * @param aspLog
     * @param e
     */
    @AfterThrowing(value = "@annotation(aspLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint,Log aspLog,Exception e){
        handleLog(joinPoint,aspLog,e,null);
    }

    /**
     * 日志處理器-記錄日志
     * @param aspLog
     * @param e
     * @param result
     */
    private void handleLog(JoinPoint joinPoint,Log aspLog,Exception e,Object result){
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        OperateLog operateLog = new OperateLog();
        operateLog.setIp(attributes.getRequest().getRemoteAddr());
        operateLog.setMethod(attributes.getRequest().getMethod());
        String param = JSON.toJSONString(joinPoint.getArgs());
        operateLog.setParam(param);
        if(e != null){
            operateLog.setErrorMsg(e.getLocalizedMessage());
        }else{
            operateLog.setSuccess(1);
            operateLog.setResult(JSON.toJSONString(result));
        }
        operateLog.setDescription(aspLog.title());
        executor.submit(() -> logService.save(operateLog));
    }
}

6. 編寫控制層代碼進(jìn)行測(cè)試

@RestController
public class TestController {
    @Log(title = "測(cè)試操作")
    @GetMapping("/test")
    public String test(){
        return "沒毛病";
    }

    @Log(title = "測(cè)試參數(shù)操作")
    @PostMapping("/testParam")
    public String testParam(@RequestBody String data){
        return data;
    }

    @Log(title = "測(cè)試異常操作")
    @GetMapping("/testExecption")
    public String testExecption(){
        return (1/0)+"";
    }
}

7. 其他注意事項(xiàng)

如果你使用的Springboot也是3.0+,在引入mybatis-plus依賴的時(shí)候,一定要導(dǎo)入mybatis-plus-spring-boot3-starter,而不是mybatis-plus-boot-starter。如果導(dǎo)入的依賴不正確,會(huì)導(dǎo)致Spring無法注入mybatis相關(guān)的內(nèi)容并報(bào)錯(cuò)。

三、功能測(cè)試與驗(yàn)證(Postman)

測(cè)試三種情況,1、測(cè)試無參get請(qǐng)求,2、測(cè)試傳參post請(qǐng)求,3、測(cè)試異常請(qǐng)求,對(duì)于成功的請(qǐng)求要在日志記錄中標(biāo)記為成功,對(duì)于異常的請(qǐng)求要記錄異常信息。

1. 測(cè)試無參get請(qǐng)求

2. 測(cè)試post帶參數(shù)請(qǐng)求

3. 測(cè)試異常請(qǐng)求

四、 總結(jié)

到這里,就完成了操作日志的記錄功能,需要注意的是,在日常開發(fā)中,一定要將記錄日志的代碼交給另一個(gè)線程執(zhí)行,避免持久化操作對(duì)主線程產(chǎn)生性能上的影響。面向切面的本質(zhì)上是對(duì)切點(diǎn)方法做了一層代理,在不影響業(yè)務(wù)代碼的前提下對(duì)其進(jìn)行功能擴(kuò)展,降低了業(yè)務(wù)代碼和非業(yè)務(wù)代碼的耦合度,這種設(shè)計(jì)適用于很多其他的業(yè)務(wù)場(chǎng)景,比如異常處理、接口性能監(jiān)控、參數(shù)校驗(yàn)與預(yù)處理等。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)操作日志記錄的完整指南的文章就介紹到這了,更多相關(guān)SpringBoot操作日志記錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)PIFrame窗體效果的示例代碼

    Java實(shí)現(xiàn)PIFrame窗體效果的示例代碼

    在很多現(xiàn)代應(yīng)用中,常常需要使用個(gè)性化的窗體外觀,擺脫傳統(tǒng)窗口邊框的限制,無邊框、透明、圓角和陰影效果使得窗體顯得更輕巧、更具視覺吸引力,同時(shí)允許用戶自由拖拽和??看绑w,所以本文給大家介紹了如何使用Java實(shí)現(xiàn)PIFrame窗體效果,需要的朋友可以參考下
    2025-03-03
  • springBoot service層事務(wù)控制的操作

    springBoot service層事務(wù)控制的操作

    這篇文章主要介紹了springBoot service層事務(wù)控制的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Spring @ExceptionHandler注解統(tǒng)一異常處理和獲取方法名

    Spring @ExceptionHandler注解統(tǒng)一異常處理和獲取方法名

    這篇文章主要介紹了Spring注解之@ExceptionHandler 統(tǒng)一異常處理和獲取方法名,在實(shí)際項(xiàng)目中,合理使用@ExceptionHandler能夠提高代碼的可維護(hù)性和用戶體驗(yàn),通過本文的解析和實(shí)踐,讀者可以更好地理解和掌握@ExceptionHandler的用法和原理
    2023-09-09
  • SpringBoot異步導(dǎo)出文件的實(shí)現(xiàn)步驟

    SpringBoot異步導(dǎo)出文件的實(shí)現(xiàn)步驟

    本文主要介紹了SpringBoot異步導(dǎo)出文件的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • IDEA中如何去掉Java方法注釋后的空行

    IDEA中如何去掉Java方法注釋后的空行

    本文介紹了如何在IntelliJIDEA中去掉Java方法注釋后多余的空行,并提供了詳細(xì)的操作步驟,通過修改設(shè)置,可以避免默認(rèn)格式化過程中自動(dòng)插入的空行,使Javadoc注釋更加緊湊和清晰,符合個(gè)人或團(tuán)隊(duì)的代碼規(guī)范
    2025-02-02
  • Spring Data JPA使用JPQL與原生SQL進(jìn)行查詢的操作

    Spring Data JPA使用JPQL與原生SQL進(jìn)行查詢的操作

    這篇文章主要介紹了Spring Data JPA使用JPQL與原生SQL進(jìn)行查詢的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • springboot如何使用mongo做日志存儲(chǔ)

    springboot如何使用mongo做日志存儲(chǔ)

    這篇文章主要介紹了springboot如何使用mongo做日志存儲(chǔ)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Mybatis order by 動(dòng)態(tài)傳參出現(xiàn)的問題及解決方法

    Mybatis order by 動(dòng)態(tài)傳參出現(xiàn)的問題及解決方法

    今天,我正在愉快地CRUD,突然發(fā)現(xiàn)出現(xiàn)一個(gè)Bug,我們來看看是怎么回事吧!接下來通過本文給大家介紹Mybatis order by 動(dòng)態(tài)傳參出現(xiàn)的一個(gè)小bug,需要的朋友可以參考下
    2021-07-07
  • java正則表達(dá)式用法大全(深度好文)

    java正則表達(dá)式用法大全(深度好文)

    這篇文章主要給大家介紹了關(guān)于java正則表達(dá)式用法大全的相關(guān)資料,正則表達(dá)式在處理字符串時(shí)非常有用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Java實(shí)現(xiàn)帶圖形界面的聊天程序

    Java實(shí)現(xiàn)帶圖形界面的聊天程序

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)帶圖形界面的聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評(píng)論

台东县| 二手房| 师宗县| 绍兴县| 申扎县| 教育| 饶平县| 富川| 广宗县| 无为县| 大冶市| 灌阳县| 沂水县| 汾阳市| 海盐县| 封丘县| 安阳市| 张家港市| 崇州市| 定西市| 洪雅县| 黔江区| 茶陵县| 桐梓县| 那坡县| 林甸县| 丰原市| 东丽区| 眉山市| 湛江市| 奉化市| 永年县| 阆中市| 白城市| 尼勒克县| 旺苍县| 尚志市| 子长县| 宿松县| 琼结县| 宿迁市|