Hi,
some time ago I wrote my own implementation of custom scope (attached
below) that, in order to cache objects, returns a Provider that keeps
its cached instance (like com.google.inject.Scopes.SINGLETON).
Today, looking at the wiki page I saw that the suggested
implementation of custom scope maintain its own map for caching
instances. Is this map needed? is my implementation broken?
Thanks,
Davide
/**
* Simple implementation of Guice scope, that admit a single active
scope a time
* and identify the lifespan of a scope with an object of type S.
*/
public class SimpleScope<S> implements Scope {
/**
* A listener for the scope event [EMAIL PROTECTED] SimpleScope#end()}
*/
public interface Listener {
void scopeBegin(Object scopeId);
void scopeEnd();
}
private S scopeId;
private List<Listener> listeners;
private final Provider<S> SCOPE_ID_PROVIDER = new Provider<S>() {
public S get() {
if (scopeId == null)
throw new IllegalStateException("In "+SimpleScope.this+"
requested
value when inactive");
return scopeId;
}
};
protected <T> SimpleScope(SimpleScope<T> parentScope) {
listeners = new ArrayList<Listener>();
if (parentScope != null) {
final Listener parentListener = new Listener() {
public void scopeEnd() {
if (scopeId != null)
end();
}
public void scopeBegin(Object x) {}
};
parentScope.registerListener( parentListener );
}
}
protected SimpleScope() {
this(null);
}
public void registerListener(Listener listener) {
listeners.add(listener);
}
public Provider<S> getActiveProvider() {
return SCOPE_ID_PROVIDER;
}
public void begin(S scopeId) {
if (scopeId == null)
throw new NullPointerException("In "+this+" null scope
identifier");
if (this.scopeId != null)
throw new IllegalStateException("In "+this+", attempted begin
("+scopeId+") when already active");
this.scopeId = scopeId;
for (Listener observer : listeners)
observer.scopeBegin(scopeId);
}
public <T> Provider<T> scope(Key<T> key, Provider<T> creator) {
SimpleScopeProvider<T> cachingProvider = new SimpleScopeProvider<T>
(creator);
listeners.add(cachingProvider);
return cachingProvider;
}
public void end() {
if (this.scopeId == null)
throw new IllegalStateException("In "+this+", attempted end()
when inactive");
for (Listener observer : listeners)
observer.scopeEnd();
scopeId = null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getName());
if (scopeId != null)
sb.append('(').append(scopeId).append(')');
return sb.toString();
}
}
/**
* Caching provider used in SimpleScope
* @author davide
*/
class SimpleScopeProvider<T> implements Provider<T>,
SimpleScope.Listener {
private final Provider<T> creator;
private volatile T instance;
public SimpleScopeProvider(Provider<T> creator) {
this.creator = creator;
}
public T get() {
if (instance == null) {
// see com.google.inject.Scopes.SINGLETON
synchronized (Injector.class) {
if (instance == null) {
instance = creator.get();
}
}
}
return instance;
}
public void scopeBegin(Object scopeId) {
T i = instance;
if (i instanceof SimpleScope.Listener)
((SimpleScope.Listener) i).scopeBegin(scopeId);
}
public void scopeEnd() {
// TODO check if any race condition may occur
T i = instance;
if (i instanceof SimpleScope.Listener)
((SimpleScope.Listener) i).scopeEnd();
instance = null;
}
public String toString() {
return creator.toString();
}
}
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en
-~----------~----~----~----~------~----~------~--~---