public class CustomizedDataSource implements DataSource {
private DataSource delegate;
...
@Override
public Connection getConnection() throws SQLException {
Connection conn = delegate.getConnection();
// customization code here
return conn;
}
}
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);
}
}
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;
}
});
...
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);
...