MCPcopy Index your code
hub / github.com/google/guice / SingletonScope

Class SingletonScope

core/src/com/google/inject/internal/SingletonScope.java:63–310  ·  view source on GitHub ↗

One instance per Injector. Also see @Singleton. Introduction from the author: Implementation of this class seems unreasonably complicated at the first sight. I fully agree with you, that the beast below is very complex and it's hard to reason on how does it work or not. S

Source from the content-addressed store, hash-verified

61 * @author timofeyb (Timothy Basanov)
62 */
63public class SingletonScope implements Scope {
64
65 /** A sentinel value representing null. */
66 private static final Object NULL = new Object();
67
68 /**
69 * Allows us to detect when circular proxies are necessary. It's only used during singleton
70 * instance initialization, after initialization direct access through volatile field is used.
71 *
72 * <p>NB: Factory uses {@link Key}s as a user locks ids, different injectors can share them.
73 * Cycles are detected properly as cycle detection does not rely on user locks ids, but error
74 * message generated could be less than ideal.
75 */
76 // TODO(user): we may use one factory per injector tree for optimization reasons
77 private static final CycleDetectingLockFactory<Key<?>> cycleDetectingLockFactory =
78 new CycleDetectingLockFactory<Key<?>>();
79
80 /**
81 * Provides singleton scope with the following properties:
82 *
83 * <ul>
84 * <li>creates no more than one instance per Key as a creator is used no more than once
85 * <li>result is cached and returned quickly on subsequent calls
86 * <li>exception in a creator is not treated as instance creation and is not cached
87 * <li>creates singletons in parallel whenever possible
88 * <li>waits for dependent singletons to be created even across threads and when dependencies
89 * are shared as long as no circular dependencies are detected
90 * <li>returns circular proxy only when circular dependencies are detected
91 * <li>aside from that, blocking synchronization is only used for proxy creation and
92 * initialization
93 * </ul>
94 *
95 * @see CycleDetectingLockFactory
96 */
97 @Override
98 public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) {
99 /** Locking strategy: */
100 return new Provider<T>() {
101 /**
102 * The lazily initialized singleton instance. Once set, this will either have type T or will
103 * be equal to NULL. Would never be reset to null.
104 *
105 * <p>Locking strategy: double-checked locking for quick exit when scope is initialized.
106 */
107 volatile Object instance;
108
109 /**
110 * Circular proxies are used when potential deadlocks are detected. Guarded by itself.
111 * ConstructionContext is not thread-safe, so each call should be synchronized.
112 *
113 * <p>Locking strategy: manipulations with proxies list or instance initialization.
114 */
115 final ConstructionContext<T> constructionContext = new ConstructionContext<>();
116
117 /**
118 * For each binding there is a separate lock that we hold during object creation.
119 *
120 * <p>Locking strategy: singleton instance creation.

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…