是否有可能在Guice范围结束时自动清理资源?

假设我使用请求范围通过Guice注入了一个Closeable对象:

 @Provides @RequestScoped public MyCloseableResource providesMyCloseableResource(){ return new MyCloseableResourceImpl(); } 

是否有可能连接一个清理方法,当范围存在时,该方法会自动调用我的资源上的close() ,而不需要求助于自定义范围实现?

查看Guice wiki上的自定义范围实现指南 ,它显示应该创建和清理范围,如下所示:

 /** * Runs {@code runnable} in batch scope. */ public void scopeRunnable(Runnable runnable) { scope.enter(); try { // explicitly seed some seed objects... scope.seed(Key.get(SomeObject.class), someObject); // create and access scoped objects runnable.run(); } finally { scope.exit(); } } 

我想知道是否有办法在finally的内置范围(特别是会话和请求范围)中连接一些自定义清理代码。

如果不可能,可能会出现阻碍这种自动清理的问题吗?

我已经找到了在servlet容器中实现相同效果的方法,通过实现Filter来为每个请求创建和清理资源,这很有效,但我很好奇它是否可能与纯Guice一起使用。

我自己遇到了类似的问题,最后推出了一个Disposable接口, Disposable提供了一个public void dispose()方法。 我发现这对于在某个地方注册监听器并需要在定义的时间取消注册它们的类特别有用。 我已经拥有的是我在博客上发表的 AttributeHolderScope ,所以我不会在这里重复这一部分。 现在唯一缺少的是AbstractAttributeHolder ,如下所示:

 /** * An anstract base class for implementing the {@link AttributeHolder} * interface which has an implementation of the attribute related methods. * * @author Matthias Treydte <waldheinz at gmail.com> */ public abstract class AbstractAttributeHolder implements AttributeHolder, Disposable { private final Object lock = new Object(); private transient Map attributes; public AbstractAttributeHolder() { this.attributes = new HashMap(); } public void replaceAttributes(Map newAttr) { synchronized (getAttributeLock()){ this.attributes = newAttr; } } @Override public Object getAttributeLock() { return this.lock; } @Override public final void putAttribute(Object key, Object value) { synchronized (getAttributeLock()) { attributes.put(key, value); } } @Override public final boolean hasAttribute(Object key) { synchronized (getAttributeLock()) { return attributes.containsKey(key); } } @Override public final Object getAttribute(Object key) { synchronized (getAttributeLock()) { return attributes.get(key); } } @Override public final Set getAttributes() { synchronized (getAttributeLock()) { return Collections.unmodifiableSet( new HashSet(this.attributes.values())); } } @Override public void dispose() { synchronized (this.getAttributeLock()) { for (Object o : this.attributes.values()) { if (o instanceof Disposable) { final Disposable d = (Disposable) o; d.dispose(); } } this.attributes.clear(); } } } 

这个类本身实现了Disposable因此您可以拥有嵌套的作用域,当您处置外部作用域时,所有嵌套作用域,更重要的是,实现Disposable所有注入实例都会被清除。 并准确地回答了你的问题:我不认为Guice本身提供的Scope实现可以实现这一点,但它可以做到。 每次我看这段代码时,我都会问自己,这是不是可以用更简洁的方式完成,但是它的工作效果非常好(至少对我而言)。