This would be fairly easy to write using Guice's SPI. Guice's Injector instance exposes a getAllBindings() method that lets you iterate through all of the bindings.
// Untested code. May need massaging.
private void closeAll(Injector injector) {
for(Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
final Binding<?> binding = entry.getValue();
if (Closeable.class.isAssignableFrom(
entry.getKey().getTypeLiteral().getRawType())) {
binding.accept(new DefaultBindingScopingVisitor<Void>() {
@Override public Void visitEagerSingleton() {
Closeable instance = (Closeable) (binding.getProvider().get());
try {
instance.close();
} catch (IOException e) {
// log this?
}
return null;
}
});
}
}
}
Note that I only overrode visitEagerSingleton
and that you may have to modify the above to handle lazily-instantiated @Singleton
instances with implicit bindings. Also note that if you bind(SomeInterface.class).to(SomeClosable.class).in(Singleton.class)
you may need to make the SomeInterface.class
Closable, though you could also instantiate every Singleton (by putting the Closable check inside the scope visitor) to determine if the provided instance itself is Closable regardless of the key. You may also be able to use Reflection on the Binding's Key to check whether the type is assignable to Closable.