1.实现一个接口
@RestController
public class LocalController {
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass());
@RequestMapping("/ac")
public WebAsyncTask<String> asyncTest() {
Callable<String> callable = () -> {
Thread.sleep(1000);
log.info("-----asyncTest-----");
return "success";
};
return new WebAsyncTask<>(callable);
}
}
非常简单
2.我们可以自定义异步的线程池,超时设置和Interceptor拦截器
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AsynInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
/**
* 异步设置
* @param configurer
*/
@Override
public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
configurer.setDefaultTimeout(60 * 1000L);
configurer.registerCallableInterceptors(timeoutInterceptor());
configurer.setTaskExecutor(threadPoolTaskExecutor());
}
/**
* 超时拦截器
* @return
*/
@Bean
public TimeoutCallableProcessingInterceptor timeoutInterceptor() {
return new TimeoutCallableProcessingInterceptor();
}
/**
* 线程池
* @return
*/
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor t = new ThreadPoolTaskExecutor();
t.setCorePoolSize(10);
t.setMaxPoolSize(50);
t.setThreadNamePrefix("YJH");
return t;
}
}
拦截器代码
public class AsynInterceptor extends HandlerInterceptorAdapter {
private static final Log log = LogFactory.getLog(MethodHandles.lookup().lookupClass());
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("preHandle");
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle");
super.postHandle(request, response, handler, modelAndView);
}
/**
* 用于处理异步请求,当Controller中有异步请求方法的时候会触发该方法时,
* 异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。
* 异步线程完成之后执行preHandle、postHandle、afterCompletion。
* @param request
* @param response
* @param handler
* @throws Exception
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
log.info("afterConcurrentHandlingStarted");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
log.info("afterCompletion");
}
}
会发现,异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。异步线程完成之后执行preHandle、postHandle、afterCompletion。
3.实现一个Filter
@Slf4j
@Order(2)
@WebFilter(urlPatterns = {"/*"}, filterName = "allFilter", asyncSupported = true)
public class AllFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
log.info("before doFilter");
chain.doFilter(request, response);
} finally {
// 判断是否异步
if (isAsyncStarted((HttpServletRequest) request) || request.isAsyncStarted()) {
log.info("AllFilter is async");
return;
}
log.info("finally doFilter");
}
}
@Override
public void destroy() {
}
protected boolean isAsyncStarted(HttpServletRequest request) {
return WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted();
}
}
asyncSupported = true一定要设置,否则会报错。