知識庫 / Spring / Spring MVC RSS 訂閱

Spring DelegatingFilterProxy 概述及使用需求

Spring MVC
HongKong
5
01:42 PM · Dec 06 ,2025

1. 概述

委託過濾器 (DelegatingFilterProxy) 是一種 Servlet 過濾器,它允許將控制傳遞給具有對 Spring 應用上下文訪問權限的 Filter 類。 Spring Security 嚴重依賴於這種技術。

在本教程中,我們將對其進行詳細介紹。

2. DelegatingFilterProxy</h2 align="left">

Javadoc 中指出,DelegatingFilterProxy 是一個

對標準 Servlet 過濾器的代理,將委託給 Spring 管理的實現 Filter 接口的 Bean。

在使用 Servlet 過濾器時,我們顯然需要在 Java-config 或 web.xml 中聲明它們為 filter-class,否則 Servlet 容器將忽略它們。 Spring 的 DelegatingFilterProxy 提供 web.xml 與應用程序上下文之間的橋樑。

2.1. DelegatingFilterProxy 內部工作原理

讓我們看看 DelegatingFilterProxy 如何將控制轉移到我們的 Spring Bean。

在初始化期間,DelegatingFilterProxy 會獲取 filter-name 並從 Spring Application Context 中檢索具有該名稱的 Bean。該 Bean 必須是類型為 jakarta.Servlet.Filter 的,即“正常”的 Servlet 過濾器。 傳入的請求將傳遞給該 Bean。

簡而言之,DelegatingFilterProxydoFilter() 方法將委託所有調用到 Spring Bean,從而使我們能夠在過濾器 Bean 中使用所有 Spring 功能。

如果使用基於 Java 的配置,我們的過濾器註冊在 ApplicationInitializer 中將定義為:

@Override
protected Filter[] getServletFilters() {
    DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
    delegateFilterProxy.setTargetBeanName("applicationFilter");
    return new Filter[]{delegateFilterProxy};
}

如果使用XML,那麼在 web.xml 文件中:

<filter>
    <filter-name>applicationFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

這意味着任何請求都可以通過 Spring 中配置為 Bean 且名稱為 applicationFilter 的過濾器進行處理。

2.2. 使用 DelegatingFilterProxy 的必要性

DelegatingFilterProxy 是 Spring Web 模塊中的一個類。它提供了一種機制,允許 HTTP 調用在到達實際目的地之前通過過濾器進行過濾。藉助 DelegatingFilterProxy,可以實現對實現 jakarta.Servlet.Filter 接口的類的注入,從而將其納入過濾器鏈。

例如,Spring Security 利用 DelegatingFilterProxy,以便可以利用 Spring 的依賴注入功能和生命週期接口,為安全過濾器提供支持。

DelegatingFilterProxy 還可以通過根據請求 URI 路徑,調用特定的或多個過濾器,在 Spring 的應用程序上下文中或 web.xml 中提供配置。

3. 創建自定義過濾器

如上所述,<em>DelegatingFilterProxy</em> 自身就是一個 servlet 過濾器,它會將請求委託給一個 Spring 管理的 bean,該 bean 實現 <em>Filter</em> 接口。

在接下來的幾個部分中,我們將創建一個自定義過濾器並使用 Java 和基於 XML 的配置進行配置。

3.1. 過濾器類

我們將創建一個簡單的過濾器,在請求進一步處理之前記錄請求信息。

首先,讓我們創建一個自定義過濾器類:

@Component("loggingFilter")
public class CustomFilter implements Filter {

    private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
        // initialize something
    }

    @Override
    public void doFilter(
      ServletRequest request, ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {
 
        HttpServletRequest req = (HttpServletRequest) request;
        LOGGER.info("Request Info : " + req);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // cleanup code, if necessary
    }
}

CustomFilter 實現 jakarta.Servlet.Filter。該類具有 @Component 註解,以便在應用程序上下文中將其註冊為 Spring Bean。 這樣,DelegatingFilterProxy 類在初始化過濾器鏈時可以找到我們的過濾器類。

請注意,Spring Bean 的名稱必須與 filter-name 中提供的自定義過濾器註冊期間的值相同,因為DelegatingFilterProxy 類將在應用程序上下文中查找具有完全相同名稱的過濾器 Bean。

如果找不到具有此名稱的 Bean,則在應用程序啓動時會引發異常。

3.2. 通過 Java 配置配置過濾器

要使用 Java 配置註冊自定義過濾器,我們需要覆蓋 <em>getServletFilters()</em> 方法,該方法位於 <em>AbstractAnnotationConfigDispatcherServletInitializer</em> 中:

public class ApplicationInitializer 
  extends AbstractAnnotationConfigDispatcherServletInitializer {
    // some other methods here
 
    @Override
    protected Filter[] getServletFilters() {
        DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
        delegateFilterProxy.setTargetBeanName("loggingFilter");
        return new Filter[]{delegateFilterProxy};
    }
}

3.3. 通過<em>web.xml</em>配置過濾器

以下是過濾器配置在<em>web.xml</em>中的示例:

<filter>
    <filter-name>loggingFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>loggingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

filter-class 參數的類型為 DelegatingFilterProxy,而不是我們創建的過濾器類。如果運行這段代碼並訪問任何 URL,則 doFilter() 方法將在 CustomFilter 中執行,並在日誌文件中顯示請求信息詳情。

4. 結論

本文介紹了 DelegatingFilterProxy 的工作原理及其使用方法。

Spring Security 廣泛使用 DelegatingFilterProxy 來保護 Web API 調用和資源免受未授權訪問。

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

發佈 評論

Some HTML is okay.