首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Servlet 啟動時初始化:load-on-startup 實現伺服器啟動自動執行

     編輯:Java 相關知識

當應用需要在伺服器啟動階段完成資料預載入、快取預熱、定時任務排程、連線池初始化等工作時,load-on-startup 配合 Servlet init() 方法是最輕量、標準的解決方案。

核心機制

  • web.xml 中 <load-on-startup> 元素指定 Servlet 載入優先級(整數,越小越早載入,0 或正整數均表示啟動時載入)。
  • 容器啟動時,按優先級實例化 Servlet 並呼叫 init(ServletConfig)。
  • init() 僅執行一次,適合一次性初始化邏輯。

完整實現代碼

1. 自動執行 Servlet


public class AutoRunServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void init() throws ServletException {
        System.out.println(">> 伺服器啟動,執行初始化邏輯 <<");
        
        // 讀取初始化參數
        String paramA = getInitParameter("a");
        System.out.println("參數 a = " + paramA);
        
        Enumeration paramNames = getInitParameterNames();
        while (paramNames.hasMoreElements()) {
            String name = paramNames.nextElement();
            System.out.println("初始化參數: " + name + " = " + getInitParameter(name));
        }
        
        // 實際業務:載入配置、預熱快取、啟動排程器等
        // DataCache.preload();
        // QuartzScheduler.start();
    }
}

2. web.xml 配置


<servlet>
    <servlet-name>AutoRunServlet</servlet-name>
    <servlet-class>com.example.AutoRunServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
    
    <init-param>
        <param-name>a</param-name>
        <param-value>啟動參數值1</param-value>
    </init-param>
    <init-param>
        <param-name>b</param-name>
        <param-value>啟動參數值2</param-value>
    </init-param>
</servlet>

啟動驗證

啟動 Tomcat,控制台輸出:

>> 伺服器啟動,執行初始化邏輯 <<
參數 a = 啟動參數值1
初始化參數: a = 啟動參數值1
初始化參數: b = 啟動參數值2

常見坑:Servlet API 衝突導致啟動失敗

錯誤現象:

jar not loaded. See Servlet Spec 2.3, section 9.7.2.
Offending class: javax/servlet/Servlet.class

原因:專案依賴包含 servlet-api.jar(如 servlet-api-2.5-6.1.14.jar),而 Tomcat lib/ 目錄下已提供 servlet-api.jar,導致同一類別由不同 ClassLoader 載入,違反 Servlet 規範 9.7.2 節。

解決方案

  1. Maven/Gradle 設為 provided:編譯時需要,打包時排除(推薦)。
  2. 手動刪除專案 WEB-INF/lib 下的 servlet-api.jar。
  3. 統一使用容器提供的版本,勿自帶。


<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

進階:Servlet 3.0+ 註解式配置


@WebServlet(
    name = "AutoRunServlet",
    urlPatterns = {"/auto-run"}, // 雖不處理請求,但規範要求
    loadOnStartup = 0,
    initParams = {
        @WebInitParam(name = "a", value = "啟動參數值1"),
        @WebInitParam(name = "b", value = "啟動參數值2")
    }
)
public class AutoRunServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        // 同上
    }
}

無需 web.xml,容器掃描註解自動註冊。

適用場景 vs 不適用場景

適用不適用
配置載入、快取預熱長時間運行的後台任務(用 ScheduledExecutorService/Quartz)
連線池/資料源初始化需用戶觸發的業務邏輯
指標註冊、健康檢查準備依賴其他未就緒服務的初始化(需延遲或重試)
單例服務啟動高併發下的延遲初始化(用 Double-Check Locking/Holder 模式)

總結

load-on-startup + init() 是 Java EE 標準的「啟動即執行」機制,零依賴、零框架、容器原生支援。記住:排除專案中的 servlet-api.jar 是避免啟動報錯的關鍵一步。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved