Class AbstractCreateStatementInterceptor

java.lang.Object
org.apache.tomcat.jdbc.pool.JdbcInterceptor
org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor
All Implemented Interfaces:
InvocationHandler
Direct Known Subclasses:
AbstractQueryReport, QueryTimeoutInterceptor, StatementDecoratorInterceptor, StatementFacade, StatementFinalizer

public abstract class AbstractCreateStatementInterceptor extends JdbcInterceptor
Abstraction interceptor. This component intercepts all calls to create some type of SQL statement. By extending this class, one can intercept queries and update statements by overriding the createStatement(Object, Method, Object[], Object, long) method.

Subclass contract. The base intercepts three things on the connection proxy, and a subclass participates in each of them:

Proxy classes come from the constructor cache described at getConstructor(int, Class); each index there is bound to one interface and a subclass must keep it that way.

  • Field Details

  • Constructor Details

    • AbstractCreateStatementInterceptor

      public AbstractCreateStatementInterceptor()
      Default constructor
  • Method Details

    • invoke

      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
      Description copied from class: JdbcInterceptor
      Gets invoked each time an operation on Connection is invoked.

      The base implementation passes the call to the next interceptor in the chain. When there is no next interceptor, the call fails fast with a NullPointerException: a chain built by the pool always ends in the ProxyConnection terminal, so reaching this case means a chain was hand-built without a terminal link. Interceptors that do not answer a call themselves continue it with super.invoke(proxy, method, args).

      Specified by:
      invoke in interface InvocationHandler
      Overrides:
      invoke in class JdbcInterceptor
      Throws:
      Throwable
    • elapsedMillis

      protected static long elapsedMillis(long startNanos)
      Measures the milliseconds elapsed since the System.nanoTime() reading taken at startNanos, rounded to the nearest millisecond.

      An interval is measured with the monotonic clock. Had it been measured with the wall clock instead, an NTP correction, a manual set, or resuming a suspended VM between the two readings could have made the difference negative, and a negative duration is never over the slow query threshold while the statistics book it as if it were real.

      Parameters:
      startNanos - the System.nanoTime() reading the measurement began with
      Returns:
      the elapsed time in milliseconds
    • getConstructor

      protected Constructor<?> getConstructor(int idx, Class<?> clazz) throws NoSuchMethodException
      Hands out the proxy constructor cached for this index. The method is safe for concurrent use: the only writer of the cache is this class's initializer, whose writes the JVM publishes to every thread that uses the class, so reading a slot needs no locking; newInstance on the returned constructor runs as it always has, outside this method. If the initializer failed to populate the index, a constructor for the requested interface is computed on demand and returned without being cached, so such calls return equivalent, but not necessarily identical, objects.
      Parameters:
      idx - - the index of the constructor
      clazz - - the interface that the proxy will implement
      Returns:
      - returns a constructor used to create new instances
      Throws:
      NoSuchMethodException - Constructor not found
      IllegalStateException - The index is already cached for a proxy class that does not implement clazz. Every use of an index in this shared cache must pass an interface that the cached proxy implements.
    • createStatement

      public abstract Object createStatement(Object proxy, Method method, Object[] args, Object statement, long time)
      This method will be invoked after a successful statement creation. This method can choose to return a wrapper around the statement or return the statement itself. If this method returns a wrapper then it should return a wrapper object that implements one of the following interfaces. Statement, PreparedStatement or CallableStatement

      An implementation must not make the statement reachable from any other code before it returns, because if this method throws then the statement is closed on a best-effort basis by the interceptor base class before the throwable is propagated to the application.

      Parameters:
      proxy - the actual proxy object
      method - the method that was called. It will be one of the methods defined in STATEMENT_TYPES
      args - the arguments to the method
      statement - the statement that the underlying connection created
      time - elapsed time in milliseconds, measured with the monotonic clock
      Returns:
      a Statement object
    • closeInvoked

      public abstract void closeInvoked()
      Method invoked when the operation Connection.close() is invoked. It runs before the close is passed down the chain, so that a hook can still reach the connection while it is alive - statements must be closed before the session is handed to the next borrower. Implementation of this method should be thought through with care, as no actions should trigger an exception. An interceptor that nevertheless throws is isolated: the exception is logged and ignored, the remaining interceptors in the chain still receive the close, and the connection is returned to the pool as it would have been. The fatal virtual machine errors the pool never swallows are the exception: those propagate.
    • isStatement

      protected boolean isStatement(Method method, boolean process)
      Returns true if the method that is being invoked matches one of the statement types.
      Parameters:
      method - the method being invoked on the proxy
      process - initial accumulator value, pass false
      Returns:
      returns true if the method name matched
    • isExecute

      protected boolean isExecute(Method method, boolean process)
      Returns true if the method that is being invoked matches one of the execute types.
      Parameters:
      method - the method being invoked on the proxy
      process - initial accumulator value, pass false
      Returns:
      returns true if the method name matched
    • process

      protected boolean process(String[] names, Method method, boolean process)
      Returns true if the method that is being invoked matches one of the method names passed in
      Parameters:
      names - list of method names that we want to intercept
      method - the method being invoked on the proxy
      process - initial accumulator value, pass false
      Returns:
      returns true if the method name matched
    • reset

      public void reset(ConnectionPool parent, PooledConnection con)
      no-op for this interceptor. no state is stored.
      Specified by:
      reset in class JdbcInterceptor
      Parameters:
      parent - - the connection pool owning the connection
      con - - the pooled connection