1 /* 2 * Copyright (C) 2006 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.internal; 18 19 import com.google.common.base.MoreObjects; 20 import com.google.common.base.Objects; 21 import com.google.common.collect.ArrayListMultimap; 22 import com.google.common.collect.ImmutableList; 23 import com.google.common.collect.ImmutableMap; 24 import com.google.common.collect.ImmutableSet; 25 import com.google.common.collect.ListMultimap; 26 import com.google.common.collect.Maps; 27 import com.google.common.collect.Sets; 28 import com.google.inject.Binder; 29 import com.google.inject.Binding; 30 import com.google.inject.ConfigurationException; 31 import com.google.inject.ImplementedBy; 32 import com.google.inject.Injector; 33 import com.google.inject.Key; 34 import com.google.inject.MembersInjector; 35 import com.google.inject.Module; 36 import com.google.inject.ProvidedBy; 37 import com.google.inject.Provider; 38 import com.google.inject.Scope; 39 import com.google.inject.Stage; 40 import com.google.inject.TypeLiteral; 41 import com.google.inject.internal.util.SourceProvider; 42 import com.google.inject.spi.BindingTargetVisitor; 43 import com.google.inject.spi.ConvertedConstantBinding; 44 import com.google.inject.spi.Dependency; 45 import com.google.inject.spi.HasDependencies; 46 import com.google.inject.spi.InjectionPoint; 47 import com.google.inject.spi.InstanceBinding; 48 import com.google.inject.spi.ProviderBinding; 49 import com.google.inject.spi.TypeConverterBinding; 50 import com.google.inject.util.Providers; 51 import java.lang.annotation.Annotation; 52 import java.lang.reflect.GenericArrayType; 53 import java.lang.reflect.InvocationTargetException; 54 import java.lang.reflect.ParameterizedType; 55 import java.lang.reflect.Type; 56 import java.util.Collections; 57 import java.util.HashSet; 58 import java.util.List; 59 import java.util.Map; 60 import java.util.Set; 61 62 /** 63 * Default {@link Injector} implementation. 64 * 65 * @author crazybob@google.com (Bob Lee) 66 */ 67 final class InjectorImpl implements Injector, Lookups { 68 public static final TypeLiteral<String> STRING_TYPE = TypeLiteral.get(String.class); 69 70 /** Options that control how the injector behaves. */ 71 static class InjectorOptions { 72 final Stage stage; 73 final boolean jitDisabled; 74 final boolean disableCircularProxies; 75 final boolean atInjectRequired; 76 final boolean exactBindingAnnotationsRequired; 77 InjectorOptions( Stage stage, boolean jitDisabled, boolean disableCircularProxies, boolean atInjectRequired, boolean exactBindingAnnotationsRequired)78 InjectorOptions( 79 Stage stage, 80 boolean jitDisabled, 81 boolean disableCircularProxies, 82 boolean atInjectRequired, 83 boolean exactBindingAnnotationsRequired) { 84 this.stage = stage; 85 this.jitDisabled = jitDisabled; 86 this.disableCircularProxies = disableCircularProxies; 87 this.atInjectRequired = atInjectRequired; 88 this.exactBindingAnnotationsRequired = exactBindingAnnotationsRequired; 89 } 90 91 @Override toString()92 public String toString() { 93 return MoreObjects.toStringHelper(getClass()) 94 .add("stage", stage) 95 .add("jitDisabled", jitDisabled) 96 .add("disableCircularProxies", disableCircularProxies) 97 .add("atInjectRequired", atInjectRequired) 98 .add("exactBindingAnnotationsRequired", exactBindingAnnotationsRequired) 99 .toString(); 100 } 101 } 102 103 /** some limitations on what just in time bindings are allowed. */ 104 enum JitLimitation { 105 /** does not allow just in time bindings */ 106 NO_JIT, 107 /** allows existing just in time bindings, but does not allow new ones */ 108 EXISTING_JIT, 109 /** allows existing just in time bindings & allows new ones to be created */ 110 NEW_OR_EXISTING_JIT, 111 } 112 113 final State state; 114 final InjectorImpl parent; 115 final ListMultimap<TypeLiteral<?>, Binding<?>> bindingsMultimap = ArrayListMultimap.create(); 116 final InjectorOptions options; 117 118 /** Just-in-time binding cache. Guarded by state.lock() */ 119 final Map<Key<?>, BindingImpl<?>> jitBindings = Maps.newHashMap(); 120 /** 121 * Cache of Keys that we were unable to create JIT bindings for, so we don't keep trying. Also 122 * guarded by state.lock(). 123 */ 124 final Set<Key<?>> failedJitBindings = Sets.newHashSet(); 125 126 Lookups lookups = new DeferredLookups(this); 127 InjectorImpl(InjectorImpl parent, State state, InjectorOptions injectorOptions)128 InjectorImpl(InjectorImpl parent, State state, InjectorOptions injectorOptions) { 129 this.parent = parent; 130 this.state = state; 131 this.options = injectorOptions; 132 133 if (parent != null) { 134 localContext = parent.localContext; 135 } else { 136 // No ThreadLocal.initialValue(), as that would cause classloader leaks. See 137 // https://github.com/google/guice/issues/288#issuecomment-48216933, 138 // https://github.com/google/guice/issues/288#issuecomment-48216944 139 localContext = new ThreadLocal<>(); 140 } 141 } 142 143 /** Indexes bindings by type. */ index()144 void index() { 145 for (Binding<?> binding : state.getExplicitBindingsThisLevel().values()) { 146 bindingsMultimap.put(binding.getKey().getTypeLiteral(), binding); 147 } 148 } 149 150 @Override findBindingsByType(TypeLiteral<T> type)151 public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) { 152 @SuppressWarnings("unchecked") // safe because we only put matching entries into the map 153 List<Binding<T>> list = (List<Binding<T>>) (List) bindingsMultimap.get(type); 154 return Collections.unmodifiableList(list); 155 } 156 157 /** Returns the binding for {@code key} */ 158 @Override getBinding(Key<T> key)159 public <T> BindingImpl<T> getBinding(Key<T> key) { 160 Errors errors = new Errors(key); 161 try { 162 BindingImpl<T> result = getBindingOrThrow(key, errors, JitLimitation.EXISTING_JIT); 163 errors.throwConfigurationExceptionIfErrorsExist(); 164 return result; 165 } catch (ErrorsException e) { 166 throw new ConfigurationException(errors.merge(e.getErrors()).getMessages()); 167 } 168 } 169 170 @Override getExistingBinding(Key<T> key)171 public <T> BindingImpl<T> getExistingBinding(Key<T> key) { 172 // Check explicit bindings, i.e. bindings created by modules. 173 BindingImpl<T> explicitBinding = state.getExplicitBinding(key); 174 if (explicitBinding != null) { 175 return explicitBinding; 176 } 177 synchronized (state.lock()) { 178 // See if any jit bindings have been created for this key. 179 for (InjectorImpl injector = this; injector != null; injector = injector.parent) { 180 @SuppressWarnings("unchecked") 181 BindingImpl<T> jitBinding = (BindingImpl<T>) injector.jitBindings.get(key); 182 if (jitBinding != null) { 183 return jitBinding; 184 } 185 } 186 } 187 188 // If Key is a Provider, we have to see if the type it is providing exists, 189 // and, if so, we have to create the binding for the provider. 190 if (isProvider(key)) { 191 try { 192 // This is safe because isProvider above ensures that T is a Provider<?> 193 @SuppressWarnings({"unchecked", "cast"}) 194 Key<?> providedKey = (Key<?>) getProvidedKey((Key) key, new Errors()); 195 if (getExistingBinding(providedKey) != null) { 196 return getBinding(key); 197 } 198 } catch (ErrorsException e) { 199 throw new ConfigurationException(e.getErrors().getMessages()); 200 } 201 } 202 203 // No existing binding exists. 204 return null; 205 } 206 207 /** 208 * Gets a binding implementation. First, it check to see if the parent has a binding. If the 209 * parent has a binding and the binding is scoped, it will use that binding. Otherwise, this 210 * checks for an explicit binding. If no explicit binding is found, it looks for a just-in-time 211 * binding. 212 */ getBindingOrThrow(Key<T> key, Errors errors, JitLimitation jitType)213 <T> BindingImpl<T> getBindingOrThrow(Key<T> key, Errors errors, JitLimitation jitType) 214 throws ErrorsException { 215 // Check explicit bindings, i.e. bindings created by modules. 216 BindingImpl<T> binding = state.getExplicitBinding(key); 217 if (binding != null) { 218 return binding; 219 } 220 221 // Look for an on-demand binding. 222 return getJustInTimeBinding(key, errors, jitType); 223 } 224 225 @Override getBinding(Class<T> type)226 public <T> Binding<T> getBinding(Class<T> type) { 227 return getBinding(Key.get(type)); 228 } 229 230 @Override getParent()231 public Injector getParent() { 232 return parent; 233 } 234 235 @Override createChildInjector(Iterable<? extends Module> modules)236 public Injector createChildInjector(Iterable<? extends Module> modules) { 237 return new InternalInjectorCreator().parentInjector(this).addModules(modules).build(); 238 } 239 240 @Override createChildInjector(Module... modules)241 public Injector createChildInjector(Module... modules) { 242 return createChildInjector(ImmutableList.copyOf(modules)); 243 } 244 245 /** 246 * Returns a just-in-time binding for {@code key}, creating it if necessary. 247 * 248 * @throws ErrorsException if the binding could not be created. 249 */ getJustInTimeBinding(Key<T> key, Errors errors, JitLimitation jitType)250 private <T> BindingImpl<T> getJustInTimeBinding(Key<T> key, Errors errors, JitLimitation jitType) 251 throws ErrorsException { 252 253 boolean jitOverride = isProvider(key) || isTypeLiteral(key) || isMembersInjector(key); 254 synchronized (state.lock()) { 255 // first try to find a JIT binding that we've already created 256 for (InjectorImpl injector = this; injector != null; injector = injector.parent) { 257 @SuppressWarnings("unchecked") // we only store bindings that match their key 258 BindingImpl<T> binding = (BindingImpl<T>) injector.jitBindings.get(key); 259 260 if (binding != null) { 261 // If we found a JIT binding and we don't allow them, 262 // fail. (But allow bindings created through TypeConverters.) 263 if (options.jitDisabled 264 && jitType == JitLimitation.NO_JIT 265 && !jitOverride 266 && !(binding instanceof ConvertedConstantBindingImpl)) { 267 throw errors.jitDisabled(key).toException(); 268 } else { 269 return binding; 270 } 271 } 272 } 273 274 // If we previously failed creating this JIT binding and our Errors has 275 // already recorded an error, then just directly throw that error. 276 // We need to do this because it's possible we already cleaned up the 277 // entry in jitBindings (during cleanup), and we may be trying 278 // to create it again (in the case of a recursive JIT binding). 279 // We need both of these guards for different reasons 280 // failedJitBindings.contains: We want to continue processing if we've never 281 // failed before, so that our initial error message contains 282 // as much useful information as possible about what errors exist. 283 // errors.hasErrors: If we haven't already failed, then it's OK to 284 // continue processing, to make sure the ultimate error message 285 // is the correct one. 286 // See: ImplicitBindingsTest#testRecursiveJitBindingsCleanupCorrectly 287 // for where this guard compes into play. 288 if (failedJitBindings.contains(key) && errors.hasErrors()) { 289 throw errors.toException(); 290 } 291 return createJustInTimeBindingRecursive(key, errors, options.jitDisabled, jitType); 292 } // end synchronized(state.lock()) 293 } 294 295 /** Returns true if the key type is Provider (but not a subclass of Provider). */ isProvider(Key<?> key)296 private static boolean isProvider(Key<?> key) { 297 return key.getTypeLiteral().getRawType().equals(Provider.class); 298 } 299 isTypeLiteral(Key<?> key)300 private static boolean isTypeLiteral(Key<?> key) { 301 return key.getTypeLiteral().getRawType().equals(TypeLiteral.class); 302 } 303 getProvidedKey(Key<Provider<T>> key, Errors errors)304 private static <T> Key<T> getProvidedKey(Key<Provider<T>> key, Errors errors) 305 throws ErrorsException { 306 Type providerType = key.getTypeLiteral().getType(); 307 308 // If the Provider has no type parameter (raw Provider)... 309 if (!(providerType instanceof ParameterizedType)) { 310 throw errors.cannotInjectRawProvider().toException(); 311 } 312 313 Type entryType = ((ParameterizedType) providerType).getActualTypeArguments()[0]; 314 315 @SuppressWarnings("unchecked") // safe because T came from Key<Provider<T>> 316 Key<T> providedKey = (Key<T>) key.ofType(entryType); 317 return providedKey; 318 } 319 320 /** Returns true if the key type is MembersInjector (but not a subclass of MembersInjector). */ isMembersInjector(Key<?> key)321 private static boolean isMembersInjector(Key<?> key) { 322 return key.getTypeLiteral().getRawType().equals(MembersInjector.class) 323 && key.getAnnotationType() == null; 324 } 325 createMembersInjectorBinding( Key<MembersInjector<T>> key, Errors errors)326 private <T> BindingImpl<MembersInjector<T>> createMembersInjectorBinding( 327 Key<MembersInjector<T>> key, Errors errors) throws ErrorsException { 328 Type membersInjectorType = key.getTypeLiteral().getType(); 329 if (!(membersInjectorType instanceof ParameterizedType)) { 330 throw errors.cannotInjectRawMembersInjector().toException(); 331 } 332 333 @SuppressWarnings("unchecked") // safe because T came from Key<MembersInjector<T>> 334 TypeLiteral<T> instanceType = 335 (TypeLiteral<T>) 336 TypeLiteral.get(((ParameterizedType) membersInjectorType).getActualTypeArguments()[0]); 337 MembersInjector<T> membersInjector = membersInjectorStore.get(instanceType, errors); 338 339 InternalFactory<MembersInjector<T>> factory = 340 new ConstantFactory<MembersInjector<T>>(Initializables.of(membersInjector)); 341 342 return new InstanceBindingImpl<MembersInjector<T>>( 343 this, 344 key, 345 SourceProvider.UNKNOWN_SOURCE, 346 factory, 347 ImmutableSet.<InjectionPoint>of(), 348 membersInjector); 349 } 350 351 /** 352 * Creates a synthetic binding to {@code Provider<T>}, i.e. a binding to the provider from {@code 353 * Binding<T>}. 354 */ createProviderBinding(Key<Provider<T>> key, Errors errors)355 private <T> BindingImpl<Provider<T>> createProviderBinding(Key<Provider<T>> key, Errors errors) 356 throws ErrorsException { 357 Key<T> providedKey = getProvidedKey(key, errors); 358 BindingImpl<T> delegate = getBindingOrThrow(providedKey, errors, JitLimitation.NO_JIT); 359 return new ProviderBindingImpl<T>(this, key, delegate); 360 } 361 362 private static class ProviderBindingImpl<T> extends BindingImpl<Provider<T>> 363 implements ProviderBinding<Provider<T>>, HasDependencies { 364 final BindingImpl<T> providedBinding; 365 ProviderBindingImpl(InjectorImpl injector, Key<Provider<T>> key, Binding<T> providedBinding)366 ProviderBindingImpl(InjectorImpl injector, Key<Provider<T>> key, Binding<T> providedBinding) { 367 super( 368 injector, 369 key, 370 providedBinding.getSource(), 371 createInternalFactory(providedBinding), 372 Scoping.UNSCOPED); 373 this.providedBinding = (BindingImpl<T>) providedBinding; 374 } 375 createInternalFactory(Binding<T> providedBinding)376 static <T> InternalFactory<Provider<T>> createInternalFactory(Binding<T> providedBinding) { 377 final Provider<T> provider = providedBinding.getProvider(); 378 return new InternalFactory<Provider<T>>() { 379 @Override 380 public Provider<T> get(InternalContext context, Dependency<?> dependency, boolean linked) { 381 return provider; 382 } 383 }; 384 } 385 386 @Override getProvidedKey()387 public Key<? extends T> getProvidedKey() { 388 return providedBinding.getKey(); 389 } 390 391 @Override acceptTargetVisitor(BindingTargetVisitor<? super Provider<T>, V> visitor)392 public <V> V acceptTargetVisitor(BindingTargetVisitor<? super Provider<T>, V> visitor) { 393 return visitor.visit(this); 394 } 395 396 @Override applyTo(Binder binder)397 public void applyTo(Binder binder) { 398 throw new UnsupportedOperationException("This element represents a synthetic binding."); 399 } 400 401 @Override toString()402 public String toString() { 403 return MoreObjects.toStringHelper(ProviderBinding.class) 404 .add("key", getKey()) 405 .add("providedKey", getProvidedKey()) 406 .toString(); 407 } 408 409 @Override getDependencies()410 public Set<Dependency<?>> getDependencies() { 411 return ImmutableSet.<Dependency<?>>of(Dependency.get(getProvidedKey())); 412 } 413 414 @Override equals(Object obj)415 public boolean equals(Object obj) { 416 if (obj instanceof ProviderBindingImpl) { 417 ProviderBindingImpl<?> o = (ProviderBindingImpl<?>) obj; 418 return getKey().equals(o.getKey()) 419 && getScoping().equals(o.getScoping()) 420 && Objects.equal(providedBinding, o.providedBinding); 421 } else { 422 return false; 423 } 424 } 425 426 @Override hashCode()427 public int hashCode() { 428 return Objects.hashCode(getKey(), getScoping(), providedBinding); 429 } 430 } 431 432 /** 433 * Converts a constant string binding to the required type. 434 * 435 * @return the binding if it could be resolved, or null if the binding doesn't exist 436 * @throws com.google.inject.internal.ErrorsException if there was an error resolving the binding 437 */ 438 private <T> BindingImpl<T> convertConstantStringBinding(Key<T> key, Errors errors) 439 throws ErrorsException { 440 // Find a constant string binding. 441 Key<String> stringKey = key.ofType(STRING_TYPE); 442 BindingImpl<String> stringBinding = state.getExplicitBinding(stringKey); 443 if (stringBinding == null || !stringBinding.isConstant()) { 444 return null; 445 } 446 447 // We can't call getProvider().get() because this InstanceBinding may not have been inintialized 448 // yet (because we may have been called during InternalInjectorCreator.initializeStatically and 449 // instance binding validation hasn't happened yet.) 450 @SuppressWarnings("unchecked") 451 String stringValue = ((InstanceBinding<String>) stringBinding).getInstance(); 452 Object source = stringBinding.getSource(); 453 454 // Find a matching type converter. 455 TypeLiteral<T> type = key.getTypeLiteral(); 456 TypeConverterBinding typeConverterBinding = 457 state.getConverter(stringValue, type, errors, source); 458 459 if (typeConverterBinding == null) { 460 // No converter can handle the given type. 461 return null; 462 } 463 464 // Try to convert the string. A failed conversion results in an error. 465 try { 466 @SuppressWarnings("unchecked") // This cast is safe because we double check below. 467 T converted = (T) typeConverterBinding.getTypeConverter().convert(stringValue, type); 468 469 if (converted == null) { 470 throw errors 471 .converterReturnedNull(stringValue, source, type, typeConverterBinding) 472 .toException(); 473 } 474 475 if (!type.getRawType().isInstance(converted)) { 476 throw errors 477 .conversionTypeError(stringValue, source, type, typeConverterBinding, converted) 478 .toException(); 479 } 480 481 return new ConvertedConstantBindingImpl<T>( 482 this, key, converted, stringBinding, typeConverterBinding); 483 } catch (ErrorsException e) { 484 throw e; 485 } catch (RuntimeException e) { 486 throw errors 487 .conversionError(stringValue, source, type, typeConverterBinding, e) 488 .toException(); 489 } 490 } 491 492 private static class ConvertedConstantBindingImpl<T> extends BindingImpl<T> 493 implements ConvertedConstantBinding<T> { 494 final T value; 495 final Provider<T> provider; 496 final Binding<String> originalBinding; 497 final TypeConverterBinding typeConverterBinding; 498 499 ConvertedConstantBindingImpl( 500 InjectorImpl injector, 501 Key<T> key, 502 T value, 503 Binding<String> originalBinding, 504 TypeConverterBinding typeConverterBinding) { 505 super( 506 injector, 507 key, 508 originalBinding.getSource(), 509 new ConstantFactory<T>(Initializables.of(value)), 510 Scoping.UNSCOPED); 511 this.value = value; 512 provider = Providers.of(value); 513 this.originalBinding = originalBinding; 514 this.typeConverterBinding = typeConverterBinding; 515 } 516 517 @Override 518 public Provider<T> getProvider() { 519 return provider; 520 } 521 522 @Override 523 public <V> V acceptTargetVisitor(BindingTargetVisitor<? super T, V> visitor) { 524 return visitor.visit(this); 525 } 526 527 @Override 528 public T getValue() { 529 return value; 530 } 531 532 @Override 533 public TypeConverterBinding getTypeConverterBinding() { 534 return typeConverterBinding; 535 } 536 537 @Override 538 public Key<String> getSourceKey() { 539 return originalBinding.getKey(); 540 } 541 542 @Override 543 public Set<Dependency<?>> getDependencies() { 544 return ImmutableSet.<Dependency<?>>of(Dependency.get(getSourceKey())); 545 } 546 547 @Override 548 public void applyTo(Binder binder) { 549 throw new UnsupportedOperationException("This element represents a synthetic binding."); 550 } 551 552 @Override 553 public String toString() { 554 return MoreObjects.toStringHelper(ConvertedConstantBinding.class) 555 .add("key", getKey()) 556 .add("sourceKey", getSourceKey()) 557 .add("value", value) 558 .toString(); 559 } 560 561 @Override 562 public boolean equals(Object obj) { 563 if (obj instanceof ConvertedConstantBindingImpl) { 564 ConvertedConstantBindingImpl<?> o = (ConvertedConstantBindingImpl<?>) obj; 565 return getKey().equals(o.getKey()) 566 && getScoping().equals(o.getScoping()) 567 && Objects.equal(value, o.value); 568 } else { 569 return false; 570 } 571 } 572 573 @Override 574 public int hashCode() { 575 return Objects.hashCode(getKey(), getScoping(), value); 576 } 577 } 578 579 <T> void initializeBinding(BindingImpl<T> binding, Errors errors) throws ErrorsException { 580 if (binding instanceof DelayedInitialize) { 581 ((DelayedInitialize) binding).initialize(this, errors); 582 } 583 } 584 585 <T> void initializeJitBinding(BindingImpl<T> binding, Errors errors) throws ErrorsException { 586 // Put the partially constructed binding in the map a little early. This enables us to handle 587 // circular dependencies. Example: FooImpl -> BarImpl -> FooImpl. 588 // Note: We don't need to synchronize on state.lock() during injector creation. 589 if (binding instanceof DelayedInitialize) { 590 Key<T> key = binding.getKey(); 591 jitBindings.put(key, binding); 592 boolean successful = false; 593 DelayedInitialize delayed = (DelayedInitialize) binding; 594 try { 595 delayed.initialize(this, errors); 596 successful = true; 597 } finally { 598 if (!successful) { 599 // We do not pass cb.getInternalConstructor as the second parameter 600 // so that cached exceptions while constructing it get stored. 601 // See TypeListenerTest#testTypeListenerThrows 602 removeFailedJitBinding(binding, null); 603 cleanup(binding, new HashSet<Key>()); 604 } 605 } 606 } 607 } 608 609 /** 610 * Iterates through the binding's dependencies to clean up any stray bindings that were leftover 611 * from a failed JIT binding. This is required because the bindings are eagerly & optimistically 612 * added to allow circular dependency support, so dependencies may pass where they should have 613 * failed. 614 */ 615 private boolean cleanup(BindingImpl<?> binding, Set<Key> encountered) { 616 boolean bindingFailed = false; 617 Set<Dependency<?>> deps = getInternalDependencies(binding); 618 for (Dependency dep : deps) { 619 Key<?> depKey = dep.getKey(); 620 InjectionPoint ip = dep.getInjectionPoint(); 621 if (encountered.add(depKey)) { // only check if we haven't looked at this key yet 622 BindingImpl depBinding = jitBindings.get(depKey); 623 if (depBinding != null) { // if the binding still exists, validate 624 boolean failed = cleanup(depBinding, encountered); // if children fail, we fail 625 if (depBinding instanceof ConstructorBindingImpl) { 626 ConstructorBindingImpl ctorBinding = (ConstructorBindingImpl) depBinding; 627 ip = ctorBinding.getInternalConstructor(); 628 if (!ctorBinding.isInitialized()) { 629 failed = true; 630 } 631 } 632 if (failed) { 633 removeFailedJitBinding(depBinding, ip); 634 bindingFailed = true; 635 } 636 } else if (state.getExplicitBinding(depKey) == null) { 637 // ignore keys if they were explicitly bound, but if neither JIT 638 // nor explicit, it's also invalid & should let parent know. 639 bindingFailed = true; 640 } 641 } 642 } 643 return bindingFailed; 644 } 645 646 /** Cleans up any state that may have been cached when constructing the JIT binding. */ 647 private void removeFailedJitBinding(Binding<?> binding, InjectionPoint ip) { 648 failedJitBindings.add(binding.getKey()); 649 jitBindings.remove(binding.getKey()); 650 membersInjectorStore.remove(binding.getKey().getTypeLiteral()); 651 provisionListenerStore.remove(binding); 652 if (ip != null) { 653 constructors.remove(ip); 654 } 655 } 656 657 /** Safely gets the dependencies of possibly not initialized bindings. */ 658 @SuppressWarnings("unchecked") 659 private Set<Dependency<?>> getInternalDependencies(BindingImpl<?> binding) { 660 if (binding instanceof ConstructorBindingImpl) { 661 return ((ConstructorBindingImpl) binding).getInternalDependencies(); 662 } else if (binding instanceof HasDependencies) { 663 return ((HasDependencies) binding).getDependencies(); 664 } else { 665 return ImmutableSet.of(); 666 } 667 } 668 669 /** 670 * Creates a binding for an injectable type with the given scope. Looks for a scope on the type if 671 * none is specified. 672 */ 673 <T> BindingImpl<T> createUninitializedBinding( 674 Key<T> key, Scoping scoping, Object source, Errors errors, boolean jitBinding) 675 throws ErrorsException { 676 Class<?> rawType = key.getTypeLiteral().getRawType(); 677 678 ImplementedBy implementedBy = rawType.getAnnotation(ImplementedBy.class); 679 680 // Don't try to inject arrays or enums annotated with @ImplementedBy. 681 if (rawType.isArray() || (rawType.isEnum() && implementedBy != null)) { 682 throw errors.missingImplementationWithHint(key, this).toException(); 683 } 684 685 // Handle TypeLiteral<T> by binding the inner type 686 if (rawType == TypeLiteral.class) { 687 @SuppressWarnings("unchecked") // we have to fudge the inner type as Object 688 BindingImpl<T> binding = 689 (BindingImpl<T>) createTypeLiteralBinding((Key<TypeLiteral<Object>>) key, errors); 690 return binding; 691 } 692 693 // Handle @ImplementedBy 694 if (implementedBy != null) { 695 Annotations.checkForMisplacedScopeAnnotations(rawType, source, errors); 696 return createImplementedByBinding(key, scoping, implementedBy, errors); 697 } 698 699 // Handle @ProvidedBy. 700 ProvidedBy providedBy = rawType.getAnnotation(ProvidedBy.class); 701 if (providedBy != null) { 702 Annotations.checkForMisplacedScopeAnnotations(rawType, source, errors); 703 return createProvidedByBinding(key, scoping, providedBy, errors); 704 } 705 706 return ConstructorBindingImpl.create( 707 this, 708 key, 709 null, /* use default constructor */ 710 source, 711 scoping, 712 errors, 713 jitBinding && options.jitDisabled, 714 options.atInjectRequired); 715 } 716 717 /** 718 * Converts a binding for a {@code Key<TypeLiteral<T>>} to the value {@code TypeLiteral<T>}. It's 719 * a bit awkward because we have to pull out the inner type in the type literal. 720 */ 721 private <T> BindingImpl<TypeLiteral<T>> createTypeLiteralBinding( 722 Key<TypeLiteral<T>> key, Errors errors) throws ErrorsException { 723 Type typeLiteralType = key.getTypeLiteral().getType(); 724 if (!(typeLiteralType instanceof ParameterizedType)) { 725 throw errors.cannotInjectRawTypeLiteral().toException(); 726 } 727 728 ParameterizedType parameterizedType = (ParameterizedType) typeLiteralType; 729 Type innerType = parameterizedType.getActualTypeArguments()[0]; 730 731 // this is unforunate. We don't support building TypeLiterals for type variable like 'T'. If 732 // this proves problematic, we can probably fix TypeLiteral to support type variables 733 if (!(innerType instanceof Class) 734 && !(innerType instanceof GenericArrayType) 735 && !(innerType instanceof ParameterizedType)) { 736 throw errors.cannotInjectTypeLiteralOf(innerType).toException(); 737 } 738 739 @SuppressWarnings("unchecked") // by definition, innerType == T, so this is safe 740 TypeLiteral<T> value = (TypeLiteral<T>) TypeLiteral.get(innerType); 741 InternalFactory<TypeLiteral<T>> factory = 742 new ConstantFactory<TypeLiteral<T>>(Initializables.of(value)); 743 return new InstanceBindingImpl<TypeLiteral<T>>( 744 this, 745 key, 746 SourceProvider.UNKNOWN_SOURCE, 747 factory, 748 ImmutableSet.<InjectionPoint>of(), 749 value); 750 } 751 752 /** Creates a binding for a type annotated with @ProvidedBy. */ 753 <T> BindingImpl<T> createProvidedByBinding( 754 Key<T> key, Scoping scoping, ProvidedBy providedBy, Errors errors) throws ErrorsException { 755 Class<?> rawType = key.getTypeLiteral().getRawType(); 756 Class<? extends javax.inject.Provider<?>> providerType = providedBy.value(); 757 758 // Make sure it's not the same type. TODO: Can we check for deeper loops? 759 if (providerType == rawType) { 760 throw errors.recursiveProviderType().toException(); 761 } 762 763 // Assume the provider provides an appropriate type. We double check at runtime. 764 @SuppressWarnings("unchecked") 765 Key<? extends Provider<T>> providerKey = (Key<? extends Provider<T>>) Key.get(providerType); 766 ProvidedByInternalFactory<T> internalFactory = 767 new ProvidedByInternalFactory<T>(rawType, providerType, providerKey); 768 Object source = rawType; 769 BindingImpl<T> binding = 770 LinkedProviderBindingImpl.createWithInitializer( 771 this, 772 key, 773 source, 774 Scoping.<T>scope(key, this, internalFactory, source, scoping), 775 scoping, 776 providerKey, 777 internalFactory); 778 internalFactory.setProvisionListenerCallback(provisionListenerStore.get(binding)); 779 return binding; 780 } 781 782 /** Creates a binding for a type annotated with @ImplementedBy. */ 783 private <T> BindingImpl<T> createImplementedByBinding( 784 Key<T> key, Scoping scoping, ImplementedBy implementedBy, Errors errors) 785 throws ErrorsException { 786 Class<?> rawType = key.getTypeLiteral().getRawType(); 787 Class<?> implementationType = implementedBy.value(); 788 789 // Make sure it's not the same type. TODO: Can we check for deeper cycles? 790 if (implementationType == rawType) { 791 throw errors.recursiveImplementationType().toException(); 792 } 793 794 // Make sure implementationType extends type. 795 if (!rawType.isAssignableFrom(implementationType)) { 796 throw errors.notASubtype(implementationType, rawType).toException(); 797 } 798 799 @SuppressWarnings("unchecked") // After the preceding check, this cast is safe. 800 Class<? extends T> subclass = (Class<? extends T>) implementationType; 801 802 // Look up the target binding. 803 final Key<? extends T> targetKey = Key.get(subclass); 804 Object source = rawType; 805 FactoryProxy<T> factory = new FactoryProxy<>(this, key, targetKey, source); 806 factory.notify(errors); // causes the factory to initialize itself internally 807 return new LinkedBindingImpl<T>( 808 this, 809 key, 810 source, 811 Scoping.<T>scope(key, this, factory, source, scoping), 812 scoping, 813 targetKey); 814 } 815 816 /** 817 * Attempts to create a just-in-time binding for {@code key} in the root injector, falling back to 818 * other ancestor injectors until this injector is tried. 819 */ 820 private <T> BindingImpl<T> createJustInTimeBindingRecursive( 821 Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType) 822 throws ErrorsException { 823 // ask the parent to create the JIT binding 824 if (parent != null) { 825 if (jitType == JitLimitation.NEW_OR_EXISTING_JIT 826 && jitDisabled 827 && !parent.options.jitDisabled) { 828 // If the binding would be forbidden here but allowed in a parent, report an error instead 829 throw errors.jitDisabledInParent(key).toException(); 830 } 831 832 try { 833 return parent.createJustInTimeBindingRecursive( 834 key, 835 new Errors(), 836 jitDisabled, 837 parent.options.jitDisabled ? JitLimitation.NO_JIT : jitType); 838 } catch (ErrorsException ignored) { 839 } 840 } 841 842 // Retrieve the sources before checking for blacklisting to guard against sources becoming null 843 // due to a full GC happening after calling state.isBlacklisted and 844 // state.getSourcesForBlacklistedKey. 845 // TODO(user): Consolidate these two APIs. 846 Set<Object> sources = state.getSourcesForBlacklistedKey(key); 847 if (state.isBlacklisted(key)) { 848 throw errors.childBindingAlreadySet(key, sources).toException(); 849 } 850 851 key = MoreTypes.canonicalizeKey(key); // before storing the key long-term, canonicalize it. 852 BindingImpl<T> binding = createJustInTimeBinding(key, errors, jitDisabled, jitType); 853 state.parent().blacklist(key, state, binding.getSource()); 854 jitBindings.put(key, binding); 855 return binding; 856 } 857 858 /** 859 * Returns a new just-in-time binding created by resolving {@code key}. The strategies used to 860 * create just-in-time bindings are: 861 * 862 * <ol> 863 * <li>Internalizing Providers. If the requested binding is for {@code Provider<T>}, we delegate 864 * to the binding for {@code T}. 865 * <li>Converting constants. 866 * <li>ImplementedBy and ProvidedBy annotations. Only for unannotated keys. 867 * <li>The constructor of the raw type. Only for unannotated keys. 868 * </ol> 869 * 870 * @throws com.google.inject.internal.ErrorsException if the binding cannot be created. 871 */ 872 private <T> BindingImpl<T> createJustInTimeBinding( 873 Key<T> key, Errors errors, boolean jitDisabled, JitLimitation jitType) 874 throws ErrorsException { 875 int numErrorsBefore = errors.size(); 876 877 // Retrieve the sources before checking for blacklisting to guard against sources becoming null 878 // due to a full GC happening after calling state.isBlacklisted and 879 // state.getSourcesForBlacklistedKey. 880 // TODO(user): Consolidate these two APIs. 881 Set<Object> sources = state.getSourcesForBlacklistedKey(key); 882 if (state.isBlacklisted(key)) { 883 throw errors.childBindingAlreadySet(key, sources).toException(); 884 } 885 886 // Handle cases where T is a Provider<?>. 887 if (isProvider(key)) { 888 // These casts are safe. We know T extends Provider<X> and that given Key<Provider<X>>, 889 // createProviderBinding() will return BindingImpl<Provider<X>>. 890 @SuppressWarnings({"unchecked", "cast"}) 891 BindingImpl<T> binding = (BindingImpl<T>) createProviderBinding((Key) key, errors); 892 return binding; 893 } 894 895 // Handle cases where T is a MembersInjector<?> 896 if (isMembersInjector(key)) { 897 // These casts are safe. T extends MembersInjector<X> and that given Key<MembersInjector<X>>, 898 // createMembersInjectorBinding() will return BindingImpl<MembersInjector<X>>. 899 @SuppressWarnings({"unchecked", "cast"}) 900 BindingImpl<T> binding = (BindingImpl<T>) createMembersInjectorBinding((Key) key, errors); 901 return binding; 902 } 903 904 // Try to convert a constant string binding to the requested type. 905 BindingImpl<T> convertedBinding = convertConstantStringBinding(key, errors); 906 if (convertedBinding != null) { 907 return convertedBinding; 908 } 909 910 if (!isTypeLiteral(key) && jitDisabled && jitType != JitLimitation.NEW_OR_EXISTING_JIT) { 911 throw errors.jitDisabled(key).toException(); 912 } 913 914 // If the key has an annotation... 915 if (key.getAnnotationType() != null) { 916 // Look for a binding without annotation attributes or return null. 917 if (key.hasAttributes() && !options.exactBindingAnnotationsRequired) { 918 try { 919 Errors ignored = new Errors(); 920 return getBindingOrThrow(key.withoutAttributes(), ignored, JitLimitation.NO_JIT); 921 } catch (ErrorsException ignored) { 922 // throw with a more appropriate message below 923 } 924 } 925 throw errors.missingImplementationWithHint(key, this).toException(); 926 } 927 928 Object source = key.getTypeLiteral().getRawType(); 929 BindingImpl<T> binding = 930 createUninitializedBinding(key, Scoping.UNSCOPED, source, errors, true); 931 errors.throwIfNewErrors(numErrorsBefore); 932 initializeJitBinding(binding, errors); 933 return binding; 934 } 935 936 <T> InternalFactory<? extends T> getInternalFactory( 937 Key<T> key, Errors errors, JitLimitation jitType) throws ErrorsException { 938 return getBindingOrThrow(key, errors, jitType).getInternalFactory(); 939 } 940 941 @Override 942 public Map<Key<?>, Binding<?>> getBindings() { 943 return state.getExplicitBindingsThisLevel(); 944 } 945 946 @Override 947 public Map<Key<?>, Binding<?>> getAllBindings() { 948 synchronized (state.lock()) { 949 return new ImmutableMap.Builder<Key<?>, Binding<?>>() 950 .putAll(state.getExplicitBindingsThisLevel()) 951 .putAll(jitBindings) 952 .build(); 953 } 954 } 955 956 @Override 957 public Map<Class<? extends Annotation>, Scope> getScopeBindings() { 958 return ImmutableMap.copyOf(state.getScopes()); 959 } 960 961 @Override 962 public Set<TypeConverterBinding> getTypeConverterBindings() { 963 return ImmutableSet.copyOf(state.getConvertersThisLevel()); 964 } 965 966 /** Returns parameter injectors, or {@code null} if there are no parameters. */ 967 SingleParameterInjector<?>[] getParametersInjectors(List<Dependency<?>> parameters, Errors errors) 968 throws ErrorsException { 969 if (parameters.isEmpty()) { 970 return null; 971 } 972 973 int numErrorsBefore = errors.size(); 974 SingleParameterInjector<?>[] result = new SingleParameterInjector<?>[parameters.size()]; 975 int i = 0; 976 for (Dependency<?> parameter : parameters) { 977 try { 978 result[i++] = createParameterInjector(parameter, errors.withSource(parameter)); 979 } catch (ErrorsException rethrownBelow) { 980 // rethrown below 981 } 982 } 983 984 errors.throwIfNewErrors(numErrorsBefore); 985 return result; 986 } 987 988 <T> SingleParameterInjector<T> createParameterInjector( 989 final Dependency<T> dependency, final Errors errors) throws ErrorsException { 990 BindingImpl<? extends T> binding = 991 getBindingOrThrow(dependency.getKey(), errors, JitLimitation.NO_JIT); 992 return new SingleParameterInjector<T>(dependency, binding); 993 } 994 995 /** Invokes a method. */ 996 interface MethodInvoker { 997 Object invoke(Object target, Object... parameters) 998 throws IllegalAccessException, InvocationTargetException; 999 } 1000 1001 /** Cached constructor injectors for each type */ 1002 final ConstructorInjectorStore constructors = new ConstructorInjectorStore(this); 1003 1004 /** Cached field and method injectors for each type. */ 1005 MembersInjectorStore membersInjectorStore; 1006 1007 /** Cached provision listener callbacks for each key. */ 1008 ProvisionListenerCallbackStore provisionListenerStore; 1009 1010 @Override 1011 @SuppressWarnings("unchecked") // the members injector type is consistent with instance's type 1012 public void injectMembers(Object instance) { 1013 MembersInjector membersInjector = getMembersInjector(instance.getClass()); 1014 membersInjector.injectMembers(instance); 1015 } 1016 1017 @Override 1018 public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) { 1019 Errors errors = new Errors(typeLiteral); 1020 try { 1021 return membersInjectorStore.get(typeLiteral, errors); 1022 } catch (ErrorsException e) { 1023 throw new ConfigurationException(errors.merge(e.getErrors()).getMessages()); 1024 } 1025 } 1026 1027 @Override 1028 public <T> MembersInjector<T> getMembersInjector(Class<T> type) { 1029 return getMembersInjector(TypeLiteral.get(type)); 1030 } 1031 1032 @Override 1033 public <T> Provider<T> getProvider(Class<T> type) { 1034 return getProvider(Key.get(type)); 1035 } 1036 1037 <T> Provider<T> getProviderOrThrow(final Dependency<T> dependency, Errors errors) 1038 throws ErrorsException { 1039 Key<T> key = dependency.getKey(); 1040 BindingImpl<? extends T> binding = getBindingOrThrow(key, errors, JitLimitation.NO_JIT); 1041 final InternalFactory<? extends T> internalFactory = binding.getInternalFactory(); 1042 final Object source = binding.getSource(); 1043 1044 return new Provider<T>() { 1045 @Override 1046 public T get() { 1047 InternalContext currentContext = enterContext(); 1048 Dependency previous = currentContext.pushDependency(dependency, source); 1049 try { 1050 T t = internalFactory.get(currentContext, dependency, false); 1051 return t; 1052 } catch (InternalProvisionException e) { 1053 throw e.addSource(dependency).toProvisionException(); 1054 } finally { 1055 currentContext.popStateAndSetDependency(previous); 1056 currentContext.close(); 1057 } 1058 } 1059 1060 @Override 1061 public String toString() { 1062 return internalFactory.toString(); 1063 } 1064 }; 1065 } 1066 1067 @Override 1068 public <T> Provider<T> getProvider(final Key<T> key) { 1069 Errors errors = new Errors(key); 1070 try { 1071 Provider<T> result = getProviderOrThrow(Dependency.get(key), errors); 1072 errors.throwIfNewErrors(0); 1073 return result; 1074 } catch (ErrorsException e) { 1075 throw new ConfigurationException(errors.merge(e.getErrors()).getMessages()); 1076 } 1077 } 1078 1079 @Override 1080 public <T> T getInstance(Key<T> key) { 1081 return getProvider(key).get(); 1082 } 1083 1084 @Override 1085 public <T> T getInstance(Class<T> type) { 1086 return getProvider(type).get(); 1087 } 1088 1089 /** 1090 * Holds Object[] as a mutable wrapper, rather than InternalContext, since array operations are 1091 * faster than ThreadLocal.set() / .get() operations. 1092 * 1093 * <p>Holds Object[] rather than InternalContext[], since localContext never gets cleaned up at 1094 * any point. This could lead to problems when, for example, an OSGI application is reloaded, the 1095 * InjectorImpl is destroyed, but the thread that the injector runs on is kept alive. In such a 1096 * case, ThreadLocal itself would hold on to a reference to localContext, which would hold on to 1097 * the old InternalContext.class object, which would hold on to the old classloader that loaded 1098 * that class, and so on. 1099 */ 1100 private final ThreadLocal<Object[]> localContext; 1101 1102 /** Only to be called by the {@link SingletonScope} provider. */ 1103 InternalContext getLocalContext() { 1104 return (InternalContext) localContext.get()[0]; 1105 } 1106 1107 /** 1108 * Looks up thread local context and {@link InternalContext#enter() enters} it or creates a new 1109 * context if necessary. 1110 * 1111 * <p>All callers of this are responsible for calling {@link InternalContext#close()}. Typical 1112 * usage should look like: 1113 * 1114 * <pre>{@code 1115 * InternalContext ctx = injector.enterContext(); 1116 * try { 1117 * ... use ctx ... 1118 * } finally { 1119 * ctx.close(); 1120 * } 1121 * }</pre> 1122 */ 1123 InternalContext enterContext() { 1124 Object[] reference = localContext.get(); 1125 if (reference == null) { 1126 reference = new Object[1]; 1127 localContext.set(reference); 1128 } 1129 InternalContext ctx = (InternalContext) reference[0]; 1130 if (ctx == null) { 1131 reference[0] = ctx = new InternalContext(options, reference); 1132 } else { 1133 ctx.enter(); 1134 } 1135 return ctx; 1136 } 1137 1138 @Override 1139 public String toString() { 1140 return MoreObjects.toStringHelper(Injector.class) 1141 .add("bindings", state.getExplicitBindingsThisLevel().values()) 1142 .toString(); 1143 } 1144 } 1145