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