對于啟用、禁止或修改特定連接或其組件的功能而言,使用攔截器無疑是一種非常強大的方式。There are many different use cases for when interceptors are useful。默認情況下,基于性能方面的考慮,連接池是無狀態的。連接池本身所插入的狀態是 defaultAutoCommit、defaultReadOnly、defaultTransactionIsolation,或 defaultCatalog(如果設置了這些狀態)。這 4 個狀態只有在連接創建時才設置。無論這些屬性是否在連接使用期間被修改,池本身都不能重置它們。
攔截器必須擴展自 org.apache.tomcat.jdbc.pool.JdbcInterceptor 類。該類相當簡單,你必須利用一個無參數構造函數。
public JdbcInterceptor() {
}
當從連接池借出一個連接時,攔截器能夠通過實現以下方法,初始化這一事件或以一些其他形式來響應該事件。
public abstract void reset(ConnectionPool parent, PooledConnection con);
上面這個方法有兩個參數,一個是連接池本身的引用 ConnectionPool parent,一個是底層連接的引用 PooledConnection con。
當調用 java.sql.Connection 對象上的方法時,會導致以下方法被調用:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
Method method 是被調用的實際方法,Object[] args 是參數。通過觀察下面這個非常簡單的例子,我們可以解釋如果當連接已經關閉時,如何讓 java.sql.Connection.close() 的調用變得無用。
if (CLOSE_VAL==method.getName()) {
if (isClosed()) return null; //noop for already closed.
}
return super.invoke(proxy,method,args);
當連接池開啟或關閉時,你可以得到相關通知。可能每個攔截器類只通知一次,即使它是一個實例方法。也可能使用當前未連接到池中的攔截器來通知你。
public void poolStarted(ConnectionPool pool) {
}
public void poolClosed(ConnectionPool pool) {
}
當重寫這些方法時,如果你擴展自 JdbcInterceptor 之外的類,不要忘記調用超類。
攔截器可以通過 jdbcInterceptors 屬性或 setJdbcInterceptors 方法來配置。攔截器也可以有屬性,可以通過如下方式來配置:
String jdbcInterceptors=
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState(useEquals=true,fast=yes)"
既然攔截器也有屬性,那么你也可以讀取其中的屬性值。你可以重寫 setProperties 方法。
public void setProperties(Map properties) {
super.setProperties(properties);
final String myprop = "myprop";
InterceptorProperty p1 = properties.get(myprop);
if (p1!=null) {
setMyprop(Long.parseLong(p1.getValue()));
}
}
連接池圍繞實際的連接創建包裝器,為的是能夠正確地池化。同樣,為了執行特定的功能,我們也可以在這些包裝器中創建攔截器。如果不需要獲取實際的連接,可以使用 javax.sql.PooledConnection 接口。
Connection con = datasource.getConnection();
Connection actual = ((javax.sql.PooledConnection)con).getConnection();
下面利用 1.6 來構建 JDBC 連接池代碼,但它也可以向后兼容到 1.5 運行時環境。為了單元測試,使用 1.6 或更高版本。
更多的關于 JDBC 用途的 Tomcat 配置范例可參看 [Tomcat 文檔]()。
構建非常簡單。池依賴于 tomcat-juli.jar,在這種情況下,需要 SlowQueryReportJmx。
javac -classpath tomcat-juli.jar \
-d . \
org/apache/tomcat/jdbc/pool/*.java \
org/apache/tomcat/jdbc/pool/interceptor/*.java \
org/apache/tomcat/jdbc/pool/jmx/*.java
構建文件位于 Tomcat 的源代碼倉庫中。
為了方便起見,在通過簡單構建命令生成所需文件的地方也包含了一個構建文件。
ant download (downloads dependencies)
ant build (compiles and generates .jar files)
ant dist (creates a release package)
ant test (runs tests, expects a test database to be setup)
系統針對 Maven 構建進行組織,但是沒有生成發布組件,只有庫本身。