对于启用、禁止或修改特定连接或其组件的功能而言,使用拦截器无疑是一种非常强大的方式。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 构建进行组织,但是没有生成发布组件,只有库本身。