🇬🇧 English | 🇨🇳 中文
A lightweight, compile-time static-proxy based JDBC interception library.
Provides interception capabilities for side-effect methods of objects such as Driver, Connection, Statement, and ResultSet.
✔ Intercept side-effect methods
✔ No bytecode enhancement
✔ No Java Agent
✔ No runtime dependencies
✔ Java 8+
Using static proxy classes generated at build time, JDBC method calls are intercepted at runtime and the corresponding listener interfaces receive the delegate and original parameters. Listeners are responsible for invoking the delegate, handling timing, exceptions, and return values as needed — the library no longer collects or forwards elapsed/exception/return information on the caller's behalf.
Maven:
<dependency>
<groupId>io.github.arowa-z</groupId>
<artifactId>jdbc-proxy</artifactId>
<version>0.0.2</version>
</dependency>Gradle:
implementation("io.github.arowa-z:jdbc-proxy:0.0.2")The published package already includes all proxy and listener implementation code; consumers do not need to enable an annotationProcessor.
import io.github.arowa.z.JdbcProxy;
import io.github.arowa.z.JdbcStatement;
import io.github.arowa.z.OnStatementExecuteQuery;
import java.sql.*;
public class Main {
public static void main(String[] args) throws Throwable {
JdbcProxy proxy = JdbcProxy.of("proxy", new OnStatementExecuteQuery() {
@Override
public ResultSet onExecuteQuery(JdbcStatement source, Statement delegate, String sql) throws SQLException {
Throwable error = null;
long elapsed = System.nanoTime();
try {
return delegate.executeQuery(sql);
} catch (Throwable throwable) {
error = throwable;
throw throwable;
} finally {
if (error != null) {
System.err.println("SQL failed: " + sql + ", err=" + error);
} else {
System.out.println("SQL succeeded: " + sql + ", elapsed (ms)=" + ((System.nanoTime() - elapsed)
/ 1_000_000));
}
}
}
});
String proxyUrl = proxy.proxyDriver("jdbc:h2:mem:test");
try (Connection connection = DriverManager.getConnection(proxyUrl);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT 1")) {
while (resultSet.next()) {
System.out.println(resultSet.getObject(1));
}
}
}
}This example demonstrates the interception model: the listener receives the real delegate and must call it (and may measure elapsed time, catch exceptions, inspect/modify results, etc.) — the library does not perform or forward timing/exception/result bookkeeping for you.
- Strong interception capability for side-effect methods
- Zero intrusion for callers
- Zero intrusion for the JVM
- Predictable behavior
- Controllable performance
- No bytecode transformation
- No classes generated at runtime
- No reflection-based proxy chains
- No Java Agent
All proxy code is generated at build time, and the final published package contains the complete implementation.
Listeners now receive the delegate object and the original method parameters and are expected to invoke the delegate themselves (if appropriate). The library no longer provides or forwards helper metadata such as method elapsed time, exception objects, or return summaries. This gives consumers full control: measure time, handle exceptions, transform or wrap return values — everything is in your hands.
Note: because listeners can control invocation, use caution to preserve expected semantics and resource handling.
Listener interfaces follow the naming format On<ClassName><MethodName>, for example OnStatementExecuteQuery, OnConnectionClose, etc.
Depends only on the standard JDBC API; no reliance on ASM, ByteBuddy, Spring, or other extra frameworks/configuration.
- SQL execution latency monitoring
- Slow query aggregation
- Error logging collection
- Auditing records
- Connection lifecycle statistics
- Database call tracing / instrumentation
- Java 8+
- Compatible with mainstream JDBC drivers
- Framework-agnostic
Because it uses static proxies, the base overhead is limited to method dispatch and listener invocation. The overall cost depends on listener implementations (for example, if listeners perform timing, synchronous I/O, or heavy processing). Keep listener work minimal for high-frequency scenarios.
Issues and PRs are welcome. Please include reproducible examples, affected JDBC methods, and Java version information when possible.
Apache License 2.0
Author: Arowa_Z — Email: Arowa_Z@outlook.com