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.