Skip to content

Instantly share code, notes, and snippets.

@brettwooldridge
Created April 11, 2015 07:37
Show Gist options
  • Save brettwooldridge/dfd21934416fc2a3c865 to your computer and use it in GitHub Desktop.
Save brettwooldridge/dfd21934416fc2a3c865 to your computer and use it in GitHub Desktop.
Intercepting DataSource
public abstract class InterceptorDataSource {
private final InvocationHandler handler;
protected InterceptorDataSource(final DataSource delegate) {
this.handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return (method.getName().equals("getConnection")) ? getConnection(delegate) : method.invoke(delegate, args);
}
};
}
protected Connection getConnection(final DataSource delegate) throws SQLException {
return delegate.getConnection();
}
public static DataSource wrapInterceptor(InterceptorDataSource instance) {
return (DataSource) Proxy.newProxyInstance(instance.getClass().getClassLoader(), new Class[] { DataSource.class }, instance.handler);
}
}
// Use case for intercepting getConnection() from HikariDataSource to do something on every
// borrow from the pool
//
HikariDataSource hikariDS = new HikariDataSource();
...
DataSource wrappedDS = InterceptorDataSource.wrapInterceptor(new InterceptorDataSource(hikariDS) {
@Override
protected Connection getConnection(DataSource delegate) throws SQLException {
final Connection c = super.getConnection(delegate);
System.out.println("Look mom, I'm wrapping HikariDataSource.getConnection() before it is given to the user");
return c;
}
});
...
// Use case for intercepting getConnection() from the real DataSource to do something on every
// connection creation (before be added to the pool)
PGSimpleDataSource realDS = new PGSimpleDataSource(); // real DataSource to intercept
DataSource wrappedDS = InterceptorDataSource.wrapInterceptor(new InterceptorDataSource(realDS) {
@Override
protected Connection getConnection(DataSource delegate) throws SQLException {
final Connection c = super.getConnection(delegate);
System.out.println("Look mom, I'm intercepting PGSimpleDataSource.getConnection() before it reaches the pool");
return c;
}
});
HikariDataSource hikariDS = new HikariDataSource();
hikariDS.setDataSource(wrappedDS);
...
@brettwooldridge
Copy link
Author

The nice thing about this interceptor, is that it works across pools with no dependency on pool-specific interceptor classes or interfaces -- making your code completely portable across pools.

@bfbay315
Copy link

bfbay315 commented Apr 3, 2020

Do you have an example ( or suggestion ) of how to intercept the connection on the way back to the pool?

@setofaces
Copy link

Do you have an example ( or suggestion ) of how to intercept the connection on the way back to the pool?

Any chance you got something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment