一、背景:
使用阿里druid數據源,可以在頁面對sql和spring bean進行調用頻次的監控,以排查慢查詢等問題,但是必須得配置一些filter,如Log4jFilter、WallConfig、StatFilter等等,一直疑惑druid中的各種filter配置與spring web項目中的filter有什麼區別和聯繫。
二、spring mvc中的Filter:
servlet用於接收get、post請求,並將處理結果返回給前端,而filter則是在servlet前後加上一些特定的處理,filter示例如下:
package com.hwm.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// do something 處理request 或response
System.out.println("filter1");
// 調用filter鏈中的下一個filter
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
過濾器通過在servlet執行過程添加過濾鏈進行實現,參考過濾器中的責任鏈模式,類似的,攔截器是通過在spring mvc執行過程中加入過濾鏈進行實現,參考攔截器中的責任鏈模式。
三、druid中的Filter:
以statFilter爲例,它是一個用於統計監控信息的過濾器,其中有一個統計連接提交的方法:
@Override
public void connection_commit(FilterChain chain, ConnectionProxy connection) throws SQLException {
chain.connection_commit(connection);
JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat();
dataSourceStat.getConnectionStat().incrementConnectionCommitCount();
}
public void connection_commit(ConnectionProxy connection) throws SQLException {
if (this.pos < filterSize) {
nextFilter().connection_commit(this, connection);//讓下一個幹活
return;
}
connection.getRawObject().commit();//都幹完了,才真正提交。這個連接也是一個代理,讓裏面真正的java.sql.connection提交。
}
private Filter nextFilter() {
Filter filter = getFilters().get(pos++);
return filter;
}
可以看出,druid過濾器也跟spring mvc過濾器一樣,運用了責任鏈模式/過濾鏈模式,其中的三要素分別爲過濾器StatFilter、過濾鏈FilterChain、目標對象ConnectionProxy,只不過傳統過濾鏈採用循環去執行過濾鏈中的過濾器方法,而druid過濾器採用了遞歸執行的方式,異曲同工。
四、結論:
兩者都利用了責任鏈模式/過濾鏈模式,雖然作用的位置不一樣,spring mvc過濾器作用在servlet service()方法前後,druid filter作用在sql事務提交前後,但是目的都是在目標對象方法的前後增加功能,且可以動態增減過濾器。
參考:
https://www.iteye.com/blog/herman-liu76-2308563
http://www.flyne.org/article/693
https://www.jianshu.com/p/36e60d72e176
https://www.jianshu.com/p/40e7c71a82d6
https://blog.csdn.net/heweimingming/article/details/79993591