Ответ 1
Я сам столкнулся с подобной проблемой и, наконец, развернул интерфейс 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<Object, Object> attributes;
public AbstractAttributeHolder() {
this.attributes = new HashMap<Object, Object>();
}
public void replaceAttributes(Map<Object, Object> 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<Object> getAttributes() {
synchronized (getAttributeLock()) {
return Collections.unmodifiableSet(
new HashSet<Object>(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
, очищаются. И чтобы точно ответить на ваш вопрос: я не думаю, что это возможно с реализациями Scope
, предоставленными самим Guice, но это можно сделать. Каждый раз, когда я смотрю на этот код, я спрашиваю себя, нельзя ли сделать это более кратким способом, но тогда он работает прекрасно (по крайней мере, для меня).