Skip to content

Commit 9abff25

Browse files
committed
Avoid re-initializing factories that are already initialized. This is necessary because we share the internal factory implementation, which leads to initialize(..) being called multiple times. There are other consequences/quirks of this, but re-initialization is the worst of it.
(cherry-picked into the 6.0 release.)
1 parent 0df8820 commit 9abff25

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

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

+23
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@ private static final class RealProviderMapProvider<K, V>
813813
extends RealMapBinderProviderWithDependencies<K, V, Map<K, Provider<V>>> {
814814
private Map<K, Provider<V>> mapOfProviders;
815815
private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
816+
private boolean initialized;
816817

817818
private RealProviderMapProvider(BindingSelection<K, V> bindingSelection) {
818819
super(bindingSelection);
@@ -825,6 +826,10 @@ public Set<Dependency<?>> getDependencies() {
825826

826827
@Override
827828
protected void doInitialize(InjectorImpl injector, Errors errors) {
829+
if (initialized) {
830+
return;
831+
}
832+
initialized = true;
828833
ImmutableMap.Builder<K, Provider<V>> mapOfProvidersBuilder = ImmutableMap.builder();
829834
ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
830835
for (Map.Entry<K, Binding<V>> entry : bindingSelection.getMapBindings().entrySet()) {
@@ -855,6 +860,8 @@ private static final class RealMapProvider<K, V>
855860

856861
K[] keys;
857862

863+
private boolean initialized = false;
864+
858865
RealMapProvider(BindingSelection<K, V> bindingSelection) {
859866
super(bindingSelection);
860867
}
@@ -865,6 +872,10 @@ BindingSelection<K, V> getBindingSelection() {
865872

866873
@Override
867874
protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
875+
if (initialized) {
876+
return;
877+
}
878+
initialized = true;
868879
@SuppressWarnings("unchecked")
869880
K[] keysArray = (K[]) new Object[bindingSelection.getMapBindings().size()];
870881
keys = keysArray;
@@ -1209,6 +1220,7 @@ private static final class RealProviderMultimapProvider<K, V>
12091220
extends RealMultimapBinderProviderWithDependencies<K, V, Map<K, Set<Provider<V>>>> {
12101221
private Map<K, Set<Provider<V>>> multimapOfProviders;
12111222
private Set<Dependency<?>> dependencies = RealMapBinder.MODULE_DEPENDENCIES;
1223+
private boolean initialized;
12121224

12131225
private RealProviderMultimapProvider(Key<Map<K, V>> mapKey) {
12141226
super(mapKey);
@@ -1221,6 +1233,10 @@ public Set<Dependency<?>> getDependencies() {
12211233

12221234
@Override
12231235
protected void doInitialize(InjectorImpl injector, Errors errors) {
1236+
if (initialized) {
1237+
return;
1238+
}
1239+
initialized = true;
12241240
ImmutableMap.Builder<K, Set<Provider<V>>> multimapOfProvidersBuilder =
12251241
ImmutableMap.builder();
12261242
ImmutableSet.Builder<Dependency<?>> dependenciesBuilder = ImmutableSet.builder();
@@ -1271,6 +1287,8 @@ private PerKeyData(K key, Binding<V>[] bindings, SingleParameterInjector<V>[] in
12711287

12721288
private PerKeyData<K, V>[] perKeyDatas;
12731289

1290+
private boolean initialized = false;
1291+
12741292
private RealMultimapProvider(Key<Map<K, V>> mapKey) {
12751293
super(mapKey);
12761294
}
@@ -1282,6 +1300,11 @@ public Set<Dependency<?>> getDependencies() {
12821300

12831301
@Override
12841302
protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException {
1303+
if (initialized) {
1304+
return;
1305+
}
1306+
initialized = true;
1307+
12851308
@SuppressWarnings({"unchecked", "rawtypes"})
12861309
PerKeyData<K, V>[] typedPerKeyData =
12871310
new PerKeyData[bindingSelection.getMapBindings().size()];

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ public int hashCode() {
749749
private abstract static class RealOptionalBinderProviderWithDependencies<T, P>
750750
extends InternalProviderInstanceBindingImpl.Factory<P> {
751751
protected final BindingSelection<T> bindingSelection;
752+
private boolean initialized = false;
752753

753754
RealOptionalBinderProviderWithDependencies(BindingSelection<T> bindingSelection) {
754755
// We need delayed initialization so we can detect jit bindings created by other bindings
@@ -760,8 +761,15 @@ private abstract static class RealOptionalBinderProviderWithDependencies<T, P>
760761

761762
@Override
762763
final void initialize(InjectorImpl injector, Errors errors) throws ErrorsException {
763-
bindingSelection.initialize(injector, errors);
764-
doInitialize();
764+
if (!initialized) {
765+
initialized = true;
766+
// Note that bindingSelection.initialize has its own guard, because multiple Factory impls
767+
// will delegate to the same bindingSelection (intentionally). The selection has some
768+
// initialization, and each factory impl has other initialization that it may additionally
769+
// do.
770+
bindingSelection.initialize(injector, errors);
771+
doInitialize();
772+
}
765773
}
766774

767775
/**

0 commit comments

Comments
 (0)