知識庫 / Spring / Spring Boot RSS 訂閱

在 Spring Boot 中註冊 ServletContextListener

Spring Boot
HongKong
4
10:43 AM · Dec 06 ,2025

1. 簡介

許多應用程序需要在啓動和關閉時執行特定的操作。Java Servlet API 提供了一種通過 ServletContextListener 接口方便地攔截這些生命週期事件的方式。 它在 Servlet 上下文創建和銷燬時接收通知,使其成為加載配置數據、啓動後台任務或初始化外部資源的好地方。

在 Java EE 應用程序中,這個監聽器通常通過 web.xml 註冊,或者更理想地使用註解 @WebListener。 Spring Boot 提供替代方案,避免 XML 配置,並與嵌入式 Servlet 容器一起工作。

在本教程中,我們將探索如何在 Spring Boot 應用程序中註冊 ServletContextListener我們將使用 Spring Boot 3.x 和 Jakarta Servlet API 實現一個簡單的監聽器,並研究基於註解和編程方式的註冊方法。

2. 實現 ServletContextListener

首先,讓我們理解 ServletContextListener 的作用。 它是一個接收關於 ServletContext 生命週期變更的接口。 ServletContextListener 允許我們在應用程序啓動和停止時運行代碼。

因此,它定義了 兩個回調方法 – contextInitialized()contextDestroyed()。 Web 容器在 Web 應用程序啓動時調用 contextInitialized(),並初始化 ServletContext。 相反,它在 Web 應用程序關閉時調用 contextDestroyed() ,即將 ServletContext 關閉。

為了演示,讓我們創建一個簡單的監聽器,用於在這些事件上記錄消息:

public class CustomLifecycleLoggingListener implements ServletContextListener {

    private final Logger log = LoggerFactory.getLogger(CustomLifecycleLoggingListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("Application started");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info(" Application stopped");
    }
}

容器在應用程序生命週期內僅調用這些方法一次,在 Web 應用程序活動之前和之後。

現在我們已經將自定義邏輯放入位置,讓我們看看如何在 Spring Boot 應用程序中註冊這個監聽器。

3. 在 Spring Boot 中註冊

在傳統的 Java EE 應用中,servlet 容器通過 @WebListener 註解檢測 servlet 監聽器。另一方面,當我們以可執行 JAR 形式運行 Spring Boot 應用時,@WebListener 類不會自動檢測。因此,我們需要顯式地註冊它們,以便調用 contextInitialized()contextDestroyed() 方法。

Spring Boot 提供了兩種常用的方法來實現此操作。

3.1. 使用 WebListenerServletComponentScan 註解

首先,我們使用 @WebListener 註解與 @ServletComponentScan 註解結合。

這需要 Servlet API 在類路徑上存在,Spring Boot 在使用  spring-boot-starter-web 時會自動包含它。我們只需要在監聽器類上添加 @WebListener 註解,並啓用 Spring Boot 應用程序中的 Servlet 組件掃描:

@SpringBootApplication
@ServletComponentScan
public class ServletContextListenerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServletContextListenerApplication.class, args);
    }
}

如果運行該應用程序,我們可以查看配置的日誌:

...
[main] INFO  o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 636 ms
[main] INFO  c.b.s.CustomLifecycleLoggingListener - Application started
[main] DEBUG o.s.w.f.ServerHttpObservationFilter - Filter 'webMvcObservationFilter' configured for use
...

總結一下,這種方法更接近傳統的Java EE風格,如果想要保持這種熟悉的模式,這是一個不錯的選擇。

3.2. 使用 ServletListenerRegistrationBean

我們也可以使用 ServletListenerRegistrationBean 來註冊我們的監聽器。

這種方法避免了 Servlet 註解,並將配置保存在 Java 代碼中。 由於它不依賴於 Servlet API 的掃描機制,因此即使在沒有 spring-boot-starter-web 的項目中也能正常工作。它還支持可執行 JAR 和 WAR 部署,無需使用 @ServletComponentScan:

@Configuration
public class CustomListenerConfiguration {

    @Bean
    public ServletListenerRegistrationBean<CustomLifecycleLoggingListener> lifecycleListener() {
        return new ServletListenerRegistrationBean<>(new CustomLifecycleLoggingListener());
    }
}

Spring 的組件掃描檢測到 ListenerConfiguration 類,並將其定義的 ServletListenerRegistrationBean 作為 Spring Bean 註冊。在應用程序啓動期間,Spring Boot 註冊了底層的 CustomLifecycleLoggingListener 類,並在應用程序生命週期中的適當時間調用其 contextInitialized()contextDestroyed() 方法.

4. 結論

在本文中,我們探討了如何在 Spring Boot 應用程序中註冊 ServletContextListener。我們實現了簡單的監聽器,並演示了兩種註冊方法——使用 @WebListener 及其 @ServletComponentScan 註解,以及 ServletListenerRegistrationBean

雖然第一種方法對於熟悉 Java EE 的開發者來説可能更熟悉,但它需要 servlet 組件掃描以及 Servlet API 在類路徑上存在。另一方面,ServletListenerRegistrationBean 是 Spring Boot 原生的註冊監聽器方式,它避免了註解,並且不依賴於 Servlet API 的掃描。

此外,還有其他註冊監聽器的方法,例如通過 servlet 初始化代碼或 XML 配置。然而,這些方法通常不建議在現代 Spring Boot 應用程序中使用。 總結起來,如果我們在構建新的 Spring Boot 應用程序或遷移代碼時,ServletListenerRegistrationBean 是更靈活和可移植的選擇。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.