拦截器 - Tomcat教程 - 极悦

Tomcat教程

全部教程

×

拦截器

对于启用、禁止或修改特定连接或其组件的功能而言,使用拦截器无疑是一种非常强大的方式。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()));
     }
  }

获取实际的 JDBC 连接

连接池围绕实际的连接创建包装器,为的是能够正确地池化。同样,为了执行特定的功能,我们也可以在这些包装器中创建拦截器。如果不需要获取实际的连接,可以使用 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 构建进行组织,但是没有生成发布组件,只有库本身。