package com.netflix.governator; import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.Maps; import com.google.inject.Key; import com.google.inject.OutOfScopeException; import com.google.inject.Provider; import com.google.inject.Scope; import com.google.inject.Scopes; import java.util.Map; public class ThreadLocalScope implements Scope { private final ThreadLocal<Map<Key<?>, Object>> content = new ThreadLocal<Map<Key<?>, Object>>(); public void enter() { checkState(content.get() == null, "ThreadLocalScope already exists in thread " + Thread.currentThread().getId()); content.set(Maps.<Key<?>, Object> newHashMap()); } public void exit() { checkState(content.get() != null, "No ThreadLocalScope found in thread " + Thread.currentThread().getId()); content.remove(); } public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) { return new Provider<T>() { public T get() { Map<Key<?>, Object> scopedObjects = content.get(); if (scopedObjects == null) { throw new OutOfScopeException("No ThreadLocalScope found in thread " + Thread.currentThread().getId()); } @SuppressWarnings("unchecked") T current = (T) scopedObjects.get(key); if (current == null && !scopedObjects.containsKey(key)) { current = unscoped.get(); // don't remember proxies; these exist only to serve // circular dependencies if (Scopes.isCircularProxy(current)) { return current; } scopedObjects.put(key, current); } return current; } }; } }