I\'m looking to create a sample project while learning Guice which uses JDBC to read/write to a SQL database. However, after years of using Spring and letting it abstract a
To inject a data source, you probably don't need to be bound to a single data source instance since the database you are connecting to features in the url. Using Guice, it is possible to force programmers to provide a binding to a DataSource implementation (link) . This data source can be injected into a ConnectionProvider to return a data source.
The connection has to be in a thread local scope. You can even implement your thread local scope but all thread local connections must be closed & removed from ThreadLocal object after commit or rollback operations to prevent memory leakage. After hacking around, I have found that you need to have a hook to the Injector object to remove ThreadLocal elements. An injector can easily be injected into your Guice AOP interceptor, some thing like this:
protected void visitThreadLocalScope(Injector injector,
DefaultBindingScopingVisitor visitor) {
if (injector == null) {
return;
}
for (Map.Entry, Binding> entry :
injector.getBindings().entrySet()) {
final Binding binding = entry.getValue();
// Not interested in the return value as yet.
binding.acceptScopingVisitor(visitor);
}
}
/**
* Default implementation that exits the thread local scope. This is
* essential to clean up and prevent any memory leakage.
*
* The scope is only visited iff the scope is an sub class of or is an
* instance of {@link ThreadLocalScope}.
*/
private static final class ExitingThreadLocalScopeVisitor
extends DefaultBindingScopingVisitor {
@Override
public Void visitScope(Scope scope) {
// ThreadLocalScope is the custom scope.
if (ThreadLocalScope.class.isAssignableFrom(scope.getClass())) {
ThreadLocalScope threadLocalScope = (ThreadLocalScope) scope;
threadLocalScope.exit();
}
return null;
}
}
Make sure you call this after the method has been invoked and closing the connection. Try this to see if this works.