Skip to content

Commit 99c1047

Browse files
lukesandbergsameb
authored andcommitted
Deprecate ProvisionListener.ProvisionInvocation.getDependencyChain()
A benchmarking experiment* shows that maintaining the dependency stack costs about 10% of guice performance. Anecdotally this feature also isn't very popular, so eliminating it seems reasonable. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=131748522
1 parent 13e9520 commit 99c1047

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

core/src/com/google/inject/internal/ProvisionListenerStackCallback.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.common.collect.Sets;
2121
import com.google.inject.Binding;
2222
import com.google.inject.ProvisionException;
23+
import com.google.inject.spi.Dependency;
2324
import com.google.inject.spi.DependencyAndSource;
2425
import com.google.inject.spi.ProvisionListener;
2526

@@ -146,6 +147,7 @@ public Binding<T> getBinding() {
146147
return binding;
147148
}
148149

150+
@Deprecated
149151
@Override
150152
public List<DependencyAndSource> getDependencyChain() {
151153
return context.getDependencyChain();

core/src/com/google/inject/spi/ProvisionListener.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,43 @@ public abstract static class ProvisionInvocation<T> {
6666

6767
/** Performs the provision, returning the object provisioned. */
6868
public abstract T provision();
69-
70-
/** Returns the dependency chain that led to this object being provisioned. */
69+
70+
/**
71+
* Returns the dependency chain that led to this object being provisioned.
72+
*
73+
* @deprecated This method is planned for removal in Guice 4.4. Some use cases can be replaced
74+
* by inferring the current chain via ThreadLocals in the listener, other use cases can use
75+
* the static dependency graph. For example,
76+
* <pre>{@code
77+
* bindListener(Matchers.any(), new MyListener());
78+
* ...
79+
*
80+
* private static final class MyListener implements ProvisionListener {
81+
* private final ThreadLocal<ArrayDeque<Binding<?>>> bindingStack =
82+
* new ThreadLocal<ArrayDeque<Binding<?>>>() {
83+
* {@literal @}Override protected ArrayDeque<Binding<?>> initialValue() {
84+
* return new ArrayDeque<>();
85+
* }
86+
* };
87+
* {@literal @}Override public <T> void onProvision(ProvisionInvocation<T> invocation) {
88+
* bindingStack.get().push(invocation.getBinding());
89+
* try {
90+
* invocation.provision();
91+
* } finally {
92+
* bindingStack.get().pop();
93+
* }
94+
* // Inspect the binding stack...
95+
* }
96+
* }
97+
*
98+
* }<pre>
99+
*
100+
* In this example the bindingStack thread local will contain a data structure that is very
101+
* similar to the data returned by this list. The main differences are that linked keys are
102+
* not in the stack, but such edges do exist in the static dependency graph (inspectable via
103+
* {@link HasDependencies#getDependencies()}), so you could infer some of the missing edges..
104+
*/
105+
@Deprecated
71106
public abstract List<DependencyAndSource> getDependencyChain();
72107

73108
}

0 commit comments

Comments
 (0)