WebAsyncManagerIntegrationFilter
介绍
字面意思这是一个Web异步管理集成过滤器,翻译成中文依然很抽象。我们从ThreadLocal讲起,ThreadLocal可以理解为一个与当前线程绑定的Map, key是当前线程,value是要存储的object。当我们在同一个线程中,可以通过get()方法获取到value。如果在A线程set(object),然后在B线程中调用get(),由于线程已切换,key是A,拿B自然取不出key为A的value。对于一个SSO系统,我们常常把当前登录的用户相关信息放到ThreadLocal中,避免每次使用的时候都去调RPC接口或者DB接口去查询。Spring Security的SecurityContextHolder就是通过ThreadLocal实现的。
WebAsyncManager,Spring文档有这么一句话:The central class for managing asynchronous request processing, mainly intended as an SPI and not typically used directly by application classes. 它主要用于异步请求,笔者发现这个东西在spring mvc请求分发处理中用到很多,时间有限,笔者也没有深入的了解,我们的主要关注点是WebAsyncManagerIntegrationFilter。
代码分析
步骤1
WebAsyncManagerIntegrationFilter#doFilterInternal()关键代码如下:
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor) asyncManager
.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
if (securityProcessingInterceptor == null) {
asyncManager.registerCallableInterceptor(CALLABLE_INTERCEPTOR_KEY,
new SecurityContextCallableProcessingInterceptor());
}
filterChain.doFilter(request, response);
}
步骤2
SecurityContextCallableProcessingInterceptor,这个拦截器的关键作用,就是执行前后存储和清空SecurityContext,以便在WebAsyncTask异步调用中获取到SecurityContext,核心代码如下:
@Override<