当过滤器的处理需要较长时间时会长时间占用一个web容器线程。
然而异步处理可以节省web容器线程
异步过滤器的配置:
设置@WebFilter的属性asyncSupport属性的值为true
或者在filter标签里使用async-supported标签进行设置
示例
@WebFilter(urlPatterns = "*", asyncSupported = true)
public class Filter1 implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
private ExecutorService service=Executors.newCachedThreadPool();//提高线程的创建性能
@Override
public void doFilter(ServletRequest req, ServletResponse arg1,
FilterChain chain) throws IOException, ServletException {
final AsyncContext context=req.startAsync();//得到异步上下文
service.submit(new AsyncRequest(context));//这样以线程池的方式来处理,在doFilter中就很简洁了
// context.start(new Runnable(){
//
// @Override
// public void run() {
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("AsyncFilter Done!");
// context.complete();
// }
//
// });
System.out.println("Filter Done!");
chain.doFilter(req, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
class AsyncRequest implements Runnable{//线程类
private AsyncContext context;
public AsyncRequest(AsyncContext context){//构造方法
this.context=context;
}
@Override
public void run() {//具体的业务
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("AsyncFilter Done!");
context.complete();
}
}
}
如果在实际中处理异步的请求,不管是Servlet还是Filter都不是最好的选择,使用监听器来完成这样的工作是最好的
与异步Servlet的关系:当过滤器是异步处理时,请求的Servlet如果也是异步处理,则获取AsyncContext实例需要使用HttpServletRequest的getAsyncContext方法