Spring Boot啟動事件詳解:類型、監聽與實戰應用

1. Spring Boot啟動事件概述

1.1 什么是Spring Boot啟動事件

在Spring Boot的應用生命周期中,從main方法執行到應用完全就緒,期間會發生一系列事件(Event)。這些事件由Spring Boot框架在特定時間點觸發,用于通知系統當前運行階段的狀態,并允許我們在這些時間點插入自定義邏輯。

可以把Spring Boot的啟動過程想象成一個舞臺劇:

  • 燈光亮起(ApplicationStartingEvent)

  • 舞臺布景準備好(ApplicationEnvironmentPreparedEvent)

  • 演員到位(ApplicationPreparedEvent)

  • 正式開演(ApplicationStartedEvent)

  • 演出完成(ApplicationReadyEvent)

  • 演出失敗(ApplicationFailedEvent)

這些事件的主要作用包括:

  1. 生命周期鉤子(Lifecycle Hooks):在特定啟動階段執行邏輯,如加載外部配置、初始化緩存等。

  2. 解耦:監聽器與事件觸發點解耦,方便擴展和維護。

  3. 可觀測性:配合日志或監控,可以跟蹤啟動進度和狀態。


1.2 事件在Spring Boot中的作用

Spring Boot事件機制主要解決了兩個問題:

  1. 啟動過程的擴展
    例如在Spring Context初始化前,我們就能通過事件拿到Environment,從而動態修改配置。

  2. 運行時狀態監聽
    例如在應用就緒后,立即啟動一個異步任務,或在啟動失敗時發送報警信息。

常見應用場景

  • ApplicationStartingEvent階段設置日志系統參數。

  • ApplicationEnvironmentPreparedEvent階段加載云端配置文件。

  • ApplicationReadyEvent階段預熱數據或啟動定時任務。

  • ApplicationFailedEvent階段上報啟動失敗的原因。

2. Spring Boot啟動事件分類

2.1 核心事件列表

Spring Boot 啟動過程中會觸發一系列標準事件,這些事件是按照應用生命周期的先后順序觸發的。核心事件包括:

事件類名觸發時機特點
ApplicationStartingEventSpringApplication.run() 剛開始執行時,且在創建 ApplicationContext 之前最早觸發的事件,可以在這里做一些全局初始化工作,如修改 Banner、初始化日志系統
ApplicationEnvironmentPreparedEvent環境變量 (Environment) 準備好,但 ApplicationContext 還未創建可以在這里讀取配置文件、動態修改配置
ApplicationContextInitializedEventApplicationContext 已創建但還未進行 Bean 加載適合做一些基于容器的初始化工作
ApplicationPreparedEventApplicationContext 已刷新(Bean 定義已加載),但還未調用 refresh() 完成可以在這里對 Bean 做調整
ApplicationStartedEvent應用已啟動,但 CommandLineRunner 和 ApplicationRunner 還未執行表示應用啟動階段已完成,馬上要進入業務邏輯階段
ApplicationReadyEvent所有 Runner 執行完畢,應用已完全就緒常用于啟動定時任務、發通知、預熱緩存
ApplicationFailedEvent啟動過程中發生異常時觸發常用于記錄錯誤日志、報警、清理資源


2.2 事件觸發的完整生命周期

下面是事件觸發的時間線,可以幫助理解它們的先后順序:

  1. ApplicationStartingEvent

    • SpringApplication 剛開始運行。

  2. ApplicationEnvironmentPreparedEvent

    • 環境(Environment)已準備好。

  3. ApplicationContextInitializedEvent

    • ApplicationContext 已初始化但未加載 Bean。

  4. ApplicationPreparedEvent

    • ApplicationContext 已準備好 Bean 定義,但未刷新。

  5. ApplicationStartedEvent

    • 應用啟動完成,Runner 未執行。

  6. ApplicationReadyEvent

    • 應用完全就緒,Runner 已執行。

  7. ApplicationFailedEvent

    • 啟動失敗時觸發(任何階段出錯都會觸發)。

💡 可以將其記為:
Start → Env → ContextInit → Prepared → Started → Ready → Failed


2.3 事件與ApplicationContext的關系

ApplicationContext 是 Spring 容器的核心,很多事件與它的生命周期緊密相關:

  • 創建前
    ApplicationStartingEventApplicationEnvironmentPreparedEvent 發生在容器創建前,這時還沒有 Bean 信息。

  • 創建中
    ApplicationContextInitializedEvent 表示容器已實例化,但 Bean 還沒加載。

  • 準備就緒
    ApplicationPreparedEvent 表示 Bean 定義已加載,可以對 Bean 做最后的調整。

  • 運行階段
    ApplicationStartedEventApplicationReadyEvent 發生在容器完全啟動后,可以安全地訪問 Bean。

  • 異常階段
    ApplicationFailedEvent 可以拿到異常和容器狀態,方便做錯誤處理。


示例代碼:打印啟動事件順序
import org.springframework.boot.context.event.*;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class StartupEventLogger implements ApplicationListener<ApplicationEvent> {@Overridepublic void onApplicationEvent(ApplicationEvent event) {System.out.println("觸發事件: " + event.getClass().getSimpleName());}
}

運行 Spring Boot 應用時,你會在控制臺看到事件觸發的順序,從而直觀了解生命周期。

3. 事件監聽方式詳解

Spring Boot 支持多種方式監聽啟動事件,主要有三種常用手段:

  1. @EventListener 注解(簡單優雅,推薦大多數場景)

  2. 實現 ApplicationListener 接口(更傳統、可精細控制)

  3. 自定義 SpringApplicationRunListener(啟動最早階段可用)


3.1 使用 @EventListener 注解

原理
@EventListener 是 Spring 4.2 引入的事件監聽方式,基于反射,方法簽名中聲明的事件類型會被自動匹配。
它最大的好處是:不需要實現接口,代碼更簡潔。

使用步驟

  1. 在 Spring Bean 中編寫一個普通方法。

  2. 方法上添加 @EventListener 注解。

  3. 方法參數為需要監聽的事件類型。

示例:監聽 ApplicationReadyEvent

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class ReadyEventListener {@EventListenerpublic void handleReady(ApplicationReadyEvent event) {System.out.println("應用已就緒,可以開始執行任務!");// 比如預熱緩存}
}

優點

  • 代碼簡潔,靈活。

  • 支持條件匹配(@EventListener(condition = ""))。

缺點

  • 無法在 Spring 容器完全創建前使用(因為需要依賴 Bean)。


3.2 實現 ApplicationListener 接口

原理
ApplicationListener 是 Spring 事件機制的傳統接口,早于 @EventListener 出現。
通過實現該接口,可以監聽指定事件類型,支持類型安全和較高性能。

使用步驟

  1. 實現 ApplicationListener<T> 接口,T 為事件類型。

  2. 將監聽器注冊為 Spring Bean(@Component 或手動注冊)。

示例:監聽 ApplicationStartedEvent

import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class StartedEventListener implements ApplicationListener<ApplicationStartedEvent> {@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {System.out.println("應用啟動完成,Runner 還未執行!");}
}

優點

  • 類型安全(編譯期即可檢查事件類型)。

  • 性能好(無反射調用)。

缺點

  • 代碼稍顯冗長。

  • 只能監聽單一類型(要監聽多個事件需多實現)。


3.3 自定義 SpringApplicationRunListener

原理
SpringApplicationRunListener 是 Spring Boot 提供的一個擴展點,用于在SpringApplication.run() 的各個階段執行邏輯。
它的生命周期比普通事件監聽器更早,甚至可以在 ApplicationContext 創建前執行邏輯。

使用步驟

  1. 實現 SpringApplicationRunListener 接口。

  2. META-INF/spring.factories 文件中注冊。

  3. 在接口方法中編寫啟動階段邏輯。

示例:記錄啟動流程

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;public class MyRunListener implements SpringApplicationRunListener {public MyRunListener(SpringApplication application, String[] args) {// 必須有這個構造器}@Overridepublic void starting() {System.out.println("【RunListener】應用啟動中...");}@Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {System.out.println("【RunListener】環境已準備好");}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {System.out.println("【RunListener】上下文已創建");}@Overridepublic void started(ConfigurableApplicationContext context) {System.out.println("【RunListener】應用已啟動");}@Overridepublic void ready(ConfigurableApplicationContext context) {System.out.println("【RunListener】應用已就緒");}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {System.out.println("【RunListener】啟動失敗:" + exception.getMessage());}
}

META-INF/spring.factories 文件注冊

org.springframework.boot.SpringApplicationRunListener=\
com.example.listener.MyRunListener

優點

  • 生命周期最早,可以做環境準備、日志初始化等。

  • 不依賴 Spring 容器。

缺點

  • 配置復雜(需在 spring.factories 注冊)。

  • 主要用于框架級擴展,不推薦業務代碼中頻繁使用。

4. 事件的實際應用場景

Spring Boot 啟動事件的真正價值,在于它可以幫我們在恰當的時間點執行關鍵任務,從而讓系統啟動更加平滑、可控。
下面我們結合常見業務場景,給出可以直接運行的示例。


4.1 初始化外部資源(如數據庫連接)

場景
有些外部資源(如數據庫連接池、消息隊列客戶端、第三方 API)需要在應用啟動早期就準備好。
如果等到業務邏輯調用時再初始化,可能會導致首個請求延遲較高。

選擇事件

  • ApplicationStartedEvent
    因為此時容器已準備好,可以安全獲取 Bean,但業務邏輯還未開始執行。

示例:初始化數據庫連接池

import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class DatabaseInitListener implements ApplicationListener<ApplicationStartedEvent> {@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {System.out.println("初始化數據庫連接池...");// 模擬初始化try {Thread.sleep(2000);System.out.println("數據庫連接池初始化完成!");} catch (InterruptedException e) {e.printStackTrace();}}
}

4.2 動態加載配置文件

場景
有時我們需要在應用啟動前,從遠程配置中心(如 Nacos、Apollo)拉取最新配置。
這必須發生在 Spring 環境 (Environment) 準備好之后,但在容器創建前。

選擇事件

  • ApplicationEnvironmentPreparedEvent
    此時可以安全讀取/修改 Environment

示例:加載遠程配置

import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;@Component
public class RemoteConfigListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {@Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment env = event.getEnvironment();System.out.println("從遠程配置中心加載配置...");// 模擬加載env.getSystemProperties().put("custom.config.source", "remote");}
}

4.3 預熱緩存數據

場景
在一些高并發系統中,首次請求往往需要加載大量數據。
為了減少冷啟動延遲,我們可以在應用就緒 (ApplicationReadyEvent) 時提前加載緩存。

選擇事件

  • ApplicationReadyEvent
    此時所有 Bean 已創建,Runner 已執行,系統處于穩定可用狀態。

示例:緩存預熱

import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class CachePreheatListener {@EventListenerpublic void onReady(ApplicationReadyEvent event) {System.out.println("應用就緒,開始預熱緩存...");// 模擬緩存預熱try {Thread.sleep(1000);System.out.println("緩存預熱完成!");} catch (InterruptedException e) {e.printStackTrace();}}
}

4.4 處理啟動失敗事件

場景
在生產環境中,啟動失敗可能意味著業務中斷,需要第一時間報警或回滾操作。

選擇事件

  • ApplicationFailedEvent
    任何階段發生異常都會觸發。

示例:啟動失敗報警

import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class StartupFailedListener implements ApplicationListener<ApplicationFailedEvent> {@Overridepublic void onApplicationEvent(ApplicationFailedEvent event) {System.err.println("應用啟動失敗,原因:" + event.getException().getMessage());// 模擬發送告警郵件}
}

5. 事件監聽的最佳實踐

事件監聽是一個很靈活的工具,但如果使用不當,可能會導致啟動變慢、邏輯混亂,甚至事件丟失。
下面從三個方面總結最佳實踐。


5.1 事件執行順序的控制

有時我們需要確保多個監聽器按指定順序執行,比如:

  • 先加載配置,再初始化數據庫

  • 先連接第三方服務,再啟動業務邏輯

Spring 提供了兩種方式來控制事件監聽器的執行順序:

方式一:@Order 注解
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;@Component
public class FirstReadyTask {@EventListener@Order(1) // 數字越小,優先級越高public void run(ApplicationReadyEvent event) {System.out.println("先執行任務A");}
}@Component
public class SecondReadyTask {@EventListener@Order(2)public void run(ApplicationReadyEvent event) {System.out.println("再執行任務B");}
}
方式二:實現 SmartApplicationListener 接口

SmartApplicationListener 提供了 getOrder() 方法,適合需要動態控制順序的場景。


5.2 異常處理與日志記錄

如果監聽器拋出未捕獲的異常,會影響啟動流程,甚至中斷應用。
建議:

  • 捕獲并記錄異常,不要讓它向外拋。

  • 對啟動非關鍵任務,異常時記錄日志但不阻斷啟動。

  • 對關鍵任務(如加載核心配置),異常時可直接退出啟動,防止系統處于錯誤狀態。

示例:異常處理模板
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class SafeStartupListener implements ApplicationListener<ApplicationStartedEvent> {@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {try {// 執行關鍵邏輯System.out.println("執行關鍵啟動任務");} catch (Exception e) {// 記錄錯誤System.err.println("啟動任務失敗:" + e.getMessage());// 選擇:中斷啟動// System.exit(1);}}
}

5.3 性能優化建議

在高并發、啟動頻繁的系統(如微服務集群)中,啟動事件的執行效率很重要。

優化建議

  1. 避免長耗時操作
    如果必須執行耗時任務(如加載大文件、調用慢API),應考慮放到異步線程中執行:

    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.event.EventListener;
    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Component;@Component
    public class AsyncCachePreheat {@Async@EventListenerpublic void onReady(ApplicationReadyEvent event) {System.out.println("異步預熱緩存...");}
    }
    
  2. 減少外部依賴的啟動阻塞
    例如遠程配置中心不可用時,可以加載本地備份配置,避免啟動失敗。

  3. 使用條件監聽
    @EventListener 支持 condition 屬性,只在滿足條件時執行監聽器:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93183.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93183.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93183.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python閉包詳解:理解閉包與可變類型和不可變類型的關系

一、定義閉包&#xff08;Closure&#xff09; 指的是一個函數對象&#xff0c;即使其外部作用域的變量已經不存在了&#xff0c;仍然能訪問這些變量。簡單來說&#xff0c;閉包是由函數及其相關的環境變量組成的實體。def outer():x 10def inner():print(x)return innerf ou…

BotCash:GPT-5發布觀察 工程優化的進步,還是技術突破的瓶頸?

BotCash&#xff1a;GPT-5發布觀察 工程優化的進步&#xff0c;還是技術突破的瓶頸&#xff1f; 在GPT-4以多模態能力震撼業界的一年后&#xff0c;GPT-5的亮相顯得有些“平靜”。當人們期待著又一場顛覆性技術革命時&#xff0c;這場發布會更像是給大模型技術按下了“精細打磨…

AJAX學習(2)

目錄 一.XMLHttpRequest 二.XMLHttpRequest——查詢參數 三.案例——地區查詢 四.XMLHttpRequest_數據提交 五.Promise 六.Promise三種狀態 七.PromiseeeXHR獲取省份列表&#xff08;案例&#xff09; 八.封裝-簡易axios-獲取省份列表 九.封裝-簡易axios-獲取地區列表 …

解決 pip 安裝包時出現的 ReadTimeoutError 方法 1: 臨時使用鏡像源(單次安裝)

解決 pip 安裝包時出現的 ReadTimeoutError 當您在使用 pip 安裝 Python 包時遇到 pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(hostfiles.pythonhosted.org, port443): Read timed out. 錯誤時&#xff0c;這通常是由于網絡問題導致的連接超時。P…

Linux下使用Samba 客戶端訪問 Samba 服務器的配置(Ubuntu Debian)

在 Linux 系統中&#xff0c;Samba 提供了與 Windows 系統文件共享的便利方式。本文將詳細介紹在 Ubuntu 和 Debian 系統下如何安裝 Samba 客戶端、訪問共享資源&#xff0c;并實現遠程目錄掛載和開機自動掛載。 文章參考自&#xff08;感謝分享&#xff09;&#xff1a;https…

解決dedecms文章默認關鍵字太短的問題

在管理文章或軟件的時候&#xff0c;大家在添加關鍵字和內容摘要的時候&#xff0c;是不是對這樣的情況感到比較的郁悶&#xff0c;我的關鍵字設定的明明非常的好&#xff0c;可是添加或修改后&#xff0c;會被無緣無故的截去很多&#xff0c;想必大家也都非常的明白&#xff0…

K8s-kubernetes(二)資源限制-詳細介紹

K8s如何合理規定對象資源使用 基本概念 Kubernetes中&#xff0c;占用資源的最小單元為單個PodKubernetes中&#xff0c;資源占用主要針對服務器的CPU、內存 為什么要做資源限制 對于Kubernetes集群而言&#xff0c;所有Pod都會占用K8s集群所在服務器的資源&#xff0c;如果不做…

量子神經網絡:從NISQ困境到邏輯比特革命的破局之路

——解析2025千比特時代開發者的機遇與行動框架 引言:量子計算的“20比特魔咒”與千比特悖論 當開發者被建議“避免在>20量子比特電路訓練”時,富士通卻宣布2025年實現10,000物理比特系統。這一矛盾揭示了量子計算從NISQ時代向FTQC時代躍遷的核心邏輯:千比特突破非為直接…

react+vite-plugin-react-router-generator自動化生成路由

前言&#xff1a;react項目實際使用中有很多提升性能與功能的插件&#xff0c;今天來說一說vite里面提供的vite-plugin-react-router-generator&#xff0c;他主要提供了自動生成路由的功能&#xff0c;配合我們的loadable/component可以實現路由的懶加載與統一管理。1、實現效…

服務器查看 GPU 占用情況的方法

在 Linux 系統中查看 GPU 占用情況&#xff0c;主要取決于你的 GPU 類型&#xff08;NVIDIA/AMD&#xff09;&#xff0c;以下是常用方法&#xff1a; 一、NVIDIA GPU&#xff08;最常用&#xff0c;如 RTX 系列、Tesla 系列&#xff09; 使用 NVIDIA 官方工具 nvidia-smi&…

【Docker實戰進階】Docker 實戰命令大全

Docker 實戰命令大全 Docker 實戰場景&#xff0c;以 Nginx 為核心示例&#xff0c;梳理容器生命周期、鏡像管理、網絡配置、數據持久化及 Compose 編排的核心命令與最佳實踐。 一、容器生命周期管理 1. 基礎生命周期命令 docker run - 創建并啟動容器 核心功能&#xff1a;基于…

PyCharm 2025.2:面向工程師的 AI 工具

引言 隨著人工智能技術的快速發展&#xff0c;AI 工程師對開發工具的需求也在不斷提升。PyCharm 2025.2 版本帶來了革命性的 AI 工具包&#xff0c;將 AI 開發所需的實驗、調試、評估和部署功能原生集成到 IDE 中。這一重大更新不僅提升了開發效率&#xff0c;也為 AI 工程師提…

爬蟲逆向--Day15--核心逆向案例2(Python逆向實現請求加密、請求堆棧、攔截器關鍵字)

一、逆向案例之Python逆向實現請求加密//具體代碼如下 function l(t, e) {return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() e.toString().toUpperCase() ? 0 : -1}function u(t) {for (var e Object.keys(t).sort(l)…

時序數據庫市場前景分析

1. 引言隨著物聯網&#xff08;IoT&#xff09;、工業互聯網、金融科技、智慧城市等領域的快速發展&#xff0c;數據呈現爆發式增長&#xff0c;其中時間序列數據&#xff08;Time-Series Data&#xff09;占據了重要地位。時序數據庫&#xff08;Time-Series Database, TSDB&a…

【網絡安全測試】Burp Suite使用指導、配置及常見問題介紹(有關必回)

Burp Suite 是**滲透測試領域事實上的標準工具**&#xff0c;尤其擅長Web應用與API安全測試。針對AI系統&#xff0c;它主要用于測試模型API、管理后臺等Web接口。以下是專業級使用指南&#xff1a;---### **一、 核心模塊與功能概覽**| **模塊** | **核心功能** | **AI測試重點…

iOS 26 一鍵登錄失效:三大運營商 SDK 無法正常獲取手機號

近期&#xff0c;不少開發者和用戶反饋&#xff0c;在升級到 iOS 26 系統后&#xff0c;App 內的 一鍵登錄功能無法正常使用。無論是移動、電信還是聯通的 SDK&#xff0c;都會出現無法獲取手機號的情況&#xff0c;導致用戶需要改用短信驗證碼或手動輸入手機號完成登錄。問題現…

OpenLayers與Vue.js結合實現前端地圖應用

OpenLayers與Vue.js結合實現前端地圖應用 下面我將為您展示如何將OpenLayers與Vue.js結合創建一個功能豐富的前端地圖應用。這個教程包含了基礎地圖展示、標記點、地圖控件以及交互功能。 實現結果 實現思路 在Vue項目中集成OpenLayers庫創建基礎地圖視圖和OSM圖層添加標記點…

VisDrone數據集,專為無人機視覺任務打造

在農業巡查、環保監測、安防布控等廣闊天地&#xff0c;無人機&#xff08;UAV&#xff09;早已超越了“拍照打卡”的酷炫標簽&#xff0c;成為不可或缺的智能之眼。然而&#xff0c;當計算機視覺模型從地面“抬頭”望向無人機視角時&#xff0c;迎接它的卻是截然不同的挑戰&am…

【Python】Python 函數基本介紹(詳細版)?

Python 函數基本介紹&#xff08;詳細版&#xff09;? 文章目錄Python 函數基本介紹&#xff08;詳細版&#xff09;?前言一、函數的創建?1.1 函數名的命名規則?1.2 函數的創建?1.3 函數的調用?二、函數的參數?2.1 形參和實參?2.2 位置參數?2.3 關鍵字參數?2.4 默認參…

【前端Vue】log-viewer組件的使用技巧

目錄 修改行號和組件的樣式 修改高亮顯示的內容和顏色 **log-viewer組件合集** 【前端Vue】如何優雅地展示帶行號的日志文件或文本內容&#xff08;log-viewer組件的使用&#xff09; 【前端Vue】使用log-viewer組件時的踩坑記錄 【前端Vue】log-viewer組件的使用技巧 【前…