diff --git a/core/src/com/google/inject/internal/RealMapBinder.java b/core/src/com/google/inject/internal/RealMapBinder.java index 52c84a09c0..6a743630cf 100644 --- a/core/src/com/google/inject/internal/RealMapBinder.java +++ b/core/src/com/google/inject/internal/RealMapBinder.java @@ -701,6 +701,7 @@ private static final class RealProviderMapProvider extends RealMapBinderProviderWithDependencies>> { private Map> mapOfProviders; private Set> dependencies = RealMapBinder.MODULE_DEPENDENCIES; + private boolean initialized; private RealProviderMapProvider(BindingSelection bindingSelection) { super(bindingSelection); @@ -713,6 +714,10 @@ public Set> getDependencies() { @Override protected void doInitialize(InjectorImpl injector, Errors errors) { + if (initialized) { + return; + } + initialized = true; ImmutableMap.Builder> mapOfProvidersBuilder = ImmutableMap.builder(); ImmutableSet.Builder> dependenciesBuilder = ImmutableSet.builder(); for (Map.Entry> entry : bindingSelection.getMapBindings().entrySet()) { @@ -743,6 +748,8 @@ private static final class RealMapProvider K[] keys; + private boolean initialized = false; + RealMapProvider(BindingSelection bindingSelection) { super(bindingSelection); } @@ -753,6 +760,10 @@ BindingSelection getBindingSelection() { @Override protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException { + if (initialized) { + return; + } + initialized = true; @SuppressWarnings("unchecked") K[] keysArray = (K[]) new Object[bindingSelection.getMapBindings().size()]; keys = keysArray; @@ -1079,6 +1090,7 @@ private static final class RealProviderMultimapProvider extends RealMultimapBinderProviderWithDependencies>>> { private Map>> multimapOfProviders; private Set> dependencies = RealMapBinder.MODULE_DEPENDENCIES; + private boolean initialized; private RealProviderMultimapProvider(Key> mapKey) { super(mapKey); @@ -1091,6 +1103,10 @@ public Set> getDependencies() { @Override protected void doInitialize(InjectorImpl injector, Errors errors) { + if (initialized) { + return; + } + initialized = true; ImmutableMap.Builder>> multimapOfProvidersBuilder = ImmutableMap.builder(); ImmutableSet.Builder> dependenciesBuilder = ImmutableSet.builder(); @@ -1141,6 +1157,8 @@ private PerKeyData(K key, Binding[] bindings, SingleParameterInjector[] in private PerKeyData[] perKeyDatas; + private boolean initialized = false; + private RealMultimapProvider(Key> mapKey) { super(mapKey); } @@ -1152,6 +1170,11 @@ public Set> getDependencies() { @Override protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException { + if (initialized) { + return; + } + initialized = true; + @SuppressWarnings({"unchecked", "rawtypes"}) PerKeyData[] typedPerKeyData = new PerKeyData[bindingSelection.getMapBindings().size()]; diff --git a/core/src/com/google/inject/internal/RealOptionalBinder.java b/core/src/com/google/inject/internal/RealOptionalBinder.java index f46771dc98..f9d0b5b869 100644 --- a/core/src/com/google/inject/internal/RealOptionalBinder.java +++ b/core/src/com/google/inject/internal/RealOptionalBinder.java @@ -706,6 +706,7 @@ public int hashCode() { private abstract static class RealOptionalBinderProviderWithDependencies extends InternalProviderInstanceBindingImpl.Factory

{ protected final BindingSelection bindingSelection; + private boolean initialized = false; RealOptionalBinderProviderWithDependencies(BindingSelection bindingSelection) { // We need delayed initialization so we can detect jit bindings created by other bindings @@ -717,8 +718,15 @@ private abstract static class RealOptionalBinderProviderWithDependencies @Override final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException { - bindingSelection.initialize(injector, errors); - doInitialize(); + if (!initialized) { + initialized = true; + // Note that bindingSelection.initialize has its own guard, because multiple Factory impls + // will delegate to the same bindingSelection (intentionally). The selection has some + // initialization, and each factory impl has other initialization that it may additionally + // do. + bindingSelection.initialize(injector, errors); + doInitialize(); + } } /**