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

Servlet 容器啟動初始化順序詳解:Listener → Filter → Servlet

     編輯:Java 相關知識

核心結論

在標準 Java Web 應用(Servlet 規範)中,三大核心組件的初始化順序固定為:

Listener > Filter > Servlet

這意味著:ServletContextListener.contextInitialized() 最先執行,其次是 Filter.init(),最後是 Servlet.init()。

代碼驗證

1. TestListener.java

package com.cos;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class TestListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("Listener 初始化。。。");
    }
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("Listener 銷毀。。。");
    }
}

2. TestFilter.java

package com.cos;
import javax.servlet.*;
import java.io.IOException;

public class TestFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 初始化。。。");
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("doFilter 。。。");
        chain.doFilter(request, response);
    }
    public void destroy() {
        System.out.println("Filter 銷毀。。。");
    }
}

3. TestServlet.java

package com.cos;
import javax.servlet.*;
import java.io.IOException;

public class TestServlet extends GenericServlet {
    @Override
    public void init(ServletConfig config) {
        System.out.println("Servlet 初始化 。。。");
    }
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        System.out.println("Servlet service 。。。");
    }
}

4. web.xml 配置(順序不影響初始化順序)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://java.sun.com/xml/ns/javaee
         https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <servlet>
        <servlet-name>s</servlet-name>
        <servlet-class>com.cos.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>s</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>f</filter-name>
        <filter-class>com.cos.TestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>f</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>com.cos.TestListener</listener-class>
    </listener>
</web-app>

控制台輸出證明

Listener 初始化。。。
Filter 初始化。。。
Servlet 初始化 。。。

為什麼是這個順序?

  1. Listener:監聽 ServletContext 生命週期,負責應用級資源初始化(如 Spring 容器啟動、連接池建立、配置加載),必須最早完成。
  2. Filter:攔截請求/響應,依賴 ServletContext 已就緒,需在 Servlet 處理請求前準備好鏈路。
  3. Servlet:具體業務處理端點,依賴 Filter 鏈已建立,最後初始化。

銷毀順序(反向)

Servlet → Filter → Listener

容器關閉時:先銷毀 Servlet 實例,再銷毀 Filter,最後觸發 contextDestroyed 釋放應用級資源。

實戰注意點

  • <load-on-startup> 只影響 Servlet 之間的相對順序,不影響 Listener/Filter。
  • 多個 Listener/Filter 時,按 web.xml 中聲明順序初始化(Listener 除外,Listener 無順序保證,但都在 Filter 之前)。
  • SpringBoot 內嵌容器(Tomcat/Jetty/Undertow)同樣遵循此規範。

總結

掌握 Listener > Filter > Servlet 初始化順序,有助於正確設計應用啟動流程:全局資源放 Listener,請求預處理放 Filter,業務邏輯放 Servlet/Controller。這是 Java Web 開發的基石知識。

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