Spring DelegatingFilterProxy

Spring 里面定义了许多 Filter. 比如 OncePerRequestFilter。

如果我们自定义OncePerRequestFilter, 则可以配置到web.xml中进行一些拦截或日志操作。

问题是如何将spring filter bean 注入到 web.xml?

发现Spring Security 中有这种例子。我就阅读了下源码。发现如下。

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>

    <!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

其中,发现了DelegatingFilterProxy 这个类。然后读了下这个class的source。

节选如下:

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // Lazily initialize the delegate if necessary.
        Filter delegateToUse = this.delegate;
        if (delegateToUse == null) {
            synchronized (this.delegateMonitor) {
                if (this.delegate == null) {
//这里在查找 applicationContext                    
WebApplicationContext wac = findWebApplicationContext();
                    if (wac == null) {
                        throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
                    }
//这里在查找代理对象
                    this.delegate = initDelegate(wac);
                }
                delegateToUse = this.delegate;
            }
        }

        // Let the delegate perform the actual doFilter operation.
        invokeDelegate(delegateToUse, request, response, filterChain);
    }

于是就清晰了。

基本上的配置就是,在web.xml 中配置 listener 初始化 spring application context.

然后配置 DelegatingFilterProxy,包装代理 FilterBean.

原文地址:https://www.cnblogs.com/lykm02/p/5056615.html