當過濾器的處理需要較長時間時會長時間佔用一個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方法