Skip to main content
 首页 » 编程设计

spring之为什么异步端点的过滤器链被调用两次

2024年08月15日10zengkefu

我正在开发一个基于 Spring boot 的应用程序。我注意到,对于异步端点,身份验证过滤器被调用两次,对于常规端点,它被调用一次。我找不到原因,但是在网上发现了一个问题https://jira.spring.io/browse/SPR-12608 ,其中据说异步端点的过滤器在异步端点执行之前和之后被调用两次。这将解释双重身份验证调用。我想知道这是预期的行为,为什么这样做以及如何避免双重身份验证。

更新: 我找到了一种方法,如何避免异步端点完成后第二次触发过滤器。我需要做的事情是分析为请求分配了哪种调度程序(如果是异步的)-在过滤器链上进一步进行。我向过滤器添加了以下方法:

@Override 
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 
        throws ServletException, IOException { 
    if (request.getDispatcherType() == DispatcherType.ASYNC) { 
        filterChain.doFilter(request, response); 
    } else { 
        super.doFilter(request, response, filterChain); 
    } 
} 

请您参考如下方法:

我看到了完全相同的行为,我认为这与异步调用被分为两个阶段这一事实有关。

首先,常规容器线程被踢出并生成临时响应,但该响应不会返回给客户端,而是被阻止,直到异步调度程序竞争为止。一旦异步线程完成处理,临时响应就会被异步线程中的真实响应替换并返回给客户端。

两个线程都经过相同的过滤器链。因此您会看到重复的调用。

如果您希望过滤器在从 OncePerRequestFilter 扩展后就被调用。它将检查您的过滤器在请求过程中是否已被调用(即使请求处理由 2 个阶段组成,每个阶段都由自己的线程处理)。