FilterChainProxy的doFilter方法如何工作?

时间:2015-03-29 23:07:51

标签: spring spring-mvc spring-security

我正在浏览org.springframework.security.web.FilterChainProxy类的源代码。我想要了解它的doFilter方法是如何工作的。以下是代码。

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException 
{
    FilterInvocation fi = new FilterInvocation(request, response, chain);
    List<Filter> filters = getFilters(fi.getRequestUrl());

    if (filters == null || filters.size() == 0) {
        if (logger.isDebugEnabled()) {
            logger.debug(fi.getRequestUrl() +
                    filters == null ? " has no matching filters" : " has an empty filter list");
        }

        chain.doFilter(request, response);

        return;
    }

    VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters);
    virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());

}

我的理解是如果我在web.xml中定义与Spring无关的自定义过滤器,它们将被包含在传递给FilterChainProxy的FilterChain对象中(我理解这是通过DelegatingFilterProxy发生的)。这是对的吗?

我认为当在web.xml中定义了非spring过滤器并且在应用程序上下文中没有定义过滤器时,会执行IF块。

VirtualFilterChain此处适用于应用程序文本中定义的过滤器。

If块中有一个return语句,阻止VirtualFilterChain部分被执行。

但是,它如何处理web.xml中定义的过滤器和应用程序上下文中定义的过滤器?

1 个答案:

答案 0 :(得分:0)

&#34; filterChain&#34;参数是指web.xml中定义的Servlet过滤器。在DelegatingFilterProxy.java中查看此代码

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) {
        ...
    }

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

invokeDelegate(...)调用FilterChainProxy的doFilter(...)方法。

List<Filter> filters = getFilters(fi.getRequestUrl());

生成一个与给定网址匹配的Spring Security过滤器列表(某些过滤器列在this section中)。

如果没有Spring Security过滤器与requestUrl匹配,则执行只会移至web.xml中定义的其余过滤器。这就是if()块的用途。

virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());

这是Spring Security过滤器的地方。调用doFilter(...)个方法。因此,例如,如果您将UsernamePasswordAuthenticationFilter配置为其中一个过滤器,则virtualFilterChain.doFilter(...)最终将调用UsernamePasswordAuthenticationFilter的doFilter(...)方法。