Filter-Chain模式簡介
定義Filter接口
public interface Filter { void doFilter(MyRequest request,MyResponse response,FilterChain chain); }
其中MyRequest,MyResponse 是自定義的類型,模擬請求過程,當然MyRequest,MyResponse可以被替換成任意一種類型
public class MyRequest { StringBuffer content; public MyRequest() { content = new StringBuffer("request"); } public MyRequest(String content){ this.content = new StringBuffer(content); } public StringBuffer getContent() { return content; } public void setContent(String content) { this.content = new StringBuffer(content); } public void append(String append){ this.content.append(append); } }
public class MyResponse { private StringBuffer content; public MyResponse() { content = new StringBuffer("response"); } public MyResponse(String content){ this.content = new StringBuffer(content); } public StringBuffer getContent() { return content; } public void setContent(String content) { this.content = new StringBuffer(content); } public void append(String append){ this.content.append(append); } }
實現Filter接口
每一個具體的Filter實現Filter接口鍾定義的doFilter方法,並在方法體鍾封裝處理邏輯。
第一個具體的Filter類,這里完全簡化處理邏輯,需要根據具體場景定義處理邏輯,時間類處理完自身職責邏輯后,將對象傳遞給FilterChain,調用FilterChain的doFilter方法,FilterChain做為中間對象傳遞給下一個Filter,稍后我們來看FilterChain這個類的實現
public class FirstFilter implements Filter{ @Override public void doFilter(MyRequest request, MyResponse response, FilterChain chain) { request.append(" firsrt Filter || "); chain.doFilter(request, response); response.append(" firsrt Filter || "); } }
第二個具體Filter類
public class SecondFilter implements Filter{ @Override public void doFilter(MyRequest request, MyResponse response, FilterChain chain) { request.append("second filter || "); chain.doFilter(request, response); response.append("second filter || "); } }
FilterChain的實現
filterchain持有一個List<Filter>的引用,並通過post標志位標記執行到哪一位的Filter,Chain的DoFileter.doFilter方法實際就是將對象傳遞給Filter,
public class FilterChain{ private List<Filter> filters; int pos = 0; public FilterChain() { filters = new LinkedList<>(); } public void addFilter(Filter filter){ filters.add(filter); } public void doFilter(MyRequest request, MyResponse response) { if(pos < filters.size()){ filters.get(pos++).doFilter(request, response, this); } } }
上訴的實現方式是Tomcat,Spring,中的實現方式,當然更見單的實現方式是每個filter持有下一個filter的引用,處理完成之后,直接調用nextFilter的方法。直到執行完畢。顯然第二種在編碼上更簡單也更容易,那么為什么許多java框架都使用第一種框架而不是使用第二種框架?個人認為i顯然在可擴展上要比低一種方式根號。FilterChain 持有Filter列表的管理和控制,這樣就filter-chain鏈的管理集中的地方,實現了維護和擴展方便。
Tomcat僅僅是在反射的基礎之上加上了Filter的使用。娘的,真厲害。