Class InjectorImpl

java.lang.Object
com.google.inject.internal.InjectorImpl
All Implemented Interfaces:
Injector, Lookups

final class InjectorImpl extends Object implements Injector, Lookups
Default Injector implementation.
  • Field Details

    • STRING_TYPE

      public static final TypeLiteral<String> STRING_TYPE
    • bindingData

      private final InjectorBindingData bindingData
    • jitBindingData

      private final InjectorJitBindingData jitBindingData
    • parent

      final InjectorImpl parent
    • options

    • lookups

      Lookups lookups
    • userRequestedMembersInjectorTypes

      final Set<TypeLiteral<?>> userRequestedMembersInjectorTypes
    • constructors

      final ConstructorInjectorStore constructors
      Cached constructor injectors for each type
    • membersInjectorStore

      MembersInjectorStore membersInjectorStore
      Cached field and method injectors for each type.
    • provisionListenerStore

      ProvisionListenerCallbackStore provisionListenerStore
      Cached provision listener callbacks for each key.
    • localContext

      private final ThreadLocal<Object[]> localContext
      Holds Object[] as a mutable wrapper, rather than InternalContext, since array operations are faster than ThreadLocal.set() / .get() operations.

      Holds Object[] rather than InternalContext[], since localContext never gets cleaned up at any point. This could lead to problems when, for example, an OSGI application is reloaded, the InjectorImpl is destroyed, but the thread that the injector runs on is kept alive. In such a case, ThreadLocal itself would hold on to a reference to localContext, which would hold on to the old InternalContext.class object, which would hold on to the old classloader that loaded that class, and so on.

  • Constructor Details

  • Method Details

    • findBindingsByType

      public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type)
      Description copied from interface: Injector
      Returns all explicit bindings for type.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      findBindingsByType in interface Injector
    • getBinding

      public <T> BindingImpl<T> getBinding(Key<T> key)
      Returns the binding for key
      Specified by:
      getBinding in interface Injector
    • getExistingBinding

      public <T> BindingImpl<T> getExistingBinding(Key<T> key)
      Description copied from interface: Injector
      Returns the binding if it already exists, or null if does not exist. Unlike Injector.getBinding(Key), this does not attempt to create just-in-time bindings for keys that aren't bound.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getExistingBinding in interface Injector
    • getBindingOrThrow

      <T> BindingImpl<T> getBindingOrThrow(Key<T> key, Errors errors, InjectorImpl.JitLimitation jitType) throws ErrorsException
      Gets a binding implementation. First, it check to see if the parent has a binding. If the parent has a binding and the binding is scoped, it will use that binding. Otherwise, this checks for an explicit binding. If no explicit binding is found, it looks for a just-in-time binding.
      Throws:
      ErrorsException
    • getBinding

      public <T> Binding<T> getBinding(Class<T> type)
      Description copied from interface: Injector
      Returns the binding for the given type. This will be an explicit bindings if the injection key was bound explicitly by a module, or an implicit binding otherwise. The implicit binding will be created if necessary.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getBinding in interface Injector
    • getParent

      public Injector getParent()
      Description copied from interface: Injector
      Returns this injector's parent, or null if this is a top-level injector.
      Specified by:
      getParent in interface Injector
    • createChildInjector

      public Injector createChildInjector(Iterable<? extends Module> modules)
      Description copied from interface: Injector
      Returns a new injector that inherits all state from this injector. All bindings, scopes, interceptors and type converters are inherited -- they are visible to the child injector. Elements of the child injector are not visible to its parent.

      Just-in-time bindings created for child injectors will be created in an ancestor injector whenever possible. This allows for scoped instances to be shared between injectors. Use explicit bindings to prevent bindings from being shared with the parent injector. Optional injections in just-in-time bindings (created in the parent injector) may be silently ignored if the optional dependencies are from the child injector.

      No key may be bound by both an injector and one of its ancestors. This includes just-in-time bindings. The lone exception is the key for Injector.class, which is bound by each injector to itself.

      Specified by:
      createChildInjector in interface Injector
    • createChildInjector

      public Injector createChildInjector(Module... modules)
      Description copied from interface: Injector
      Returns a new injector that inherits all state from this injector. All bindings, scopes, interceptors and type converters are inherited -- they are visible to the child injector. Elements of the child injector are not visible to its parent.

      Just-in-time bindings created for child injectors will be created in an ancestor injector whenever possible. This allows for scoped instances to be shared between injectors. Use explicit bindings to prevent bindings from being shared with the parent injector.

      No key may be bound by both an injector and one of its ancestors. This includes just-in-time bindings. The lone exception is the key for Injector.class, which is bound by each injector to itself.

      Specified by:
      createChildInjector in interface Injector
    • getBindingData

      InjectorBindingData getBindingData()
    • getJitBindingData

      InjectorJitBindingData getJitBindingData()
    • getJustInTimeBinding

      private <T> BindingImpl<T> getJustInTimeBinding(Key<T> key, Errors errors, InjectorImpl.JitLimitation jitType) throws ErrorsException
      Returns a just-in-time binding for key, creating it if necessary.
      Throws:
      ErrorsException - if the binding could not be created.
    • isProvider

      private static boolean isProvider(Key<?> key)
      Returns true if the key type is Provider (but not a subclass of Provider).
    • isTypeLiteral

      private static boolean isTypeLiteral(Key<?> key)
    • getProvidedKey

      private static <T> Key<T> getProvidedKey(Key<Provider<T>> key, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • isMembersInjector

      private static boolean isMembersInjector(Key<?> key)
      Returns true if the key type is MembersInjector (but not a subclass of MembersInjector).
    • createMembersInjectorBinding

      private <T> BindingImpl<MembersInjector<T>> createMembersInjectorBinding(Key<MembersInjector<T>> key, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • createSyntheticProviderBinding

      private <T> BindingImpl<Provider<T>> createSyntheticProviderBinding(Key<Provider<T>> key, Errors errors) throws ErrorsException
      Creates a synthetic binding to Provider<T>, i.e. a framework-created JIT binding to the provider from Binding<T>.
      Throws:
      ErrorsException
    • convertConstantStringBinding

      private <T> BindingImpl<T> convertConstantStringBinding(Key<T> key, Errors errors) throws ErrorsException
      Converts a constant string binding to the required type.
      Returns:
      the binding if it could be resolved, or null if the binding doesn't exist
      Throws:
      ErrorsException - if there was an error resolving the binding
    • initializeBinding

      <T> void initializeBinding(BindingImpl<T> binding, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • initializeJitBinding

      <T> void initializeJitBinding(BindingImpl<T> binding, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • cleanup

      private boolean cleanup(BindingImpl<?> binding, Set<Key<?>> encountered)
      Iterates through the binding's dependencies to clean up any stray bindings that were leftover from a failed JIT binding. This is required because the bindings are eagerly invalid input: '&' optimistically added to allow circular dependency support, so dependencies may pass where they should have failed.
    • removeFailedJitBinding

      private void removeFailedJitBinding(Binding<?> binding, InjectionPoint ip)
      Cleans up any state that may have been cached when constructing the JIT binding.
    • getInternalDependencies

      private Set<Dependency<?>> getInternalDependencies(BindingImpl<?> binding)
      Safely gets the dependencies of possibly not initialized bindings.
    • createUninitializedBinding

      <T> BindingImpl<T> createUninitializedBinding(Key<T> key, Scoping scoping, Object source, Errors errors, boolean jitBinding) throws ErrorsException
      Creates a binding for an injectable type with the given scope. Looks for a scope on the type if none is specified.
      Throws:
      ErrorsException
    • createTypeLiteralBinding

      private <T> BindingImpl<TypeLiteral<T>> createTypeLiteralBinding(Key<TypeLiteral<T>> key, Errors errors) throws ErrorsException
      Converts a binding for a Key<TypeLiteral<T>> to the value TypeLiteral<T>. It's a bit awkward because we have to pull out the inner type in the type literal.
      Throws:
      ErrorsException
    • createProvidedByBinding

      <T> BindingImpl<T> createProvidedByBinding(Key<T> key, Scoping scoping, ProvidedBy providedBy, Errors errors) throws ErrorsException
      Creates a binding for a type annotated with @ProvidedBy.
      Throws:
      ErrorsException
    • createImplementedByBinding

      private <T> BindingImpl<T> createImplementedByBinding(Key<T> key, Scoping scoping, ImplementedBy implementedBy, Errors errors) throws ErrorsException
      Creates a binding for a type annotated with @ImplementedBy.
      Throws:
      ErrorsException
    • createJustInTimeBindingRecursive

      private <T> BindingImpl<T> createJustInTimeBindingRecursive(Key<T> key, Errors errors, boolean jitDisabled, InjectorImpl.JitLimitation jitType) throws ErrorsException
      Attempts to create a just-in-time binding for key in the root injector, falling back to other ancestor injectors until this injector is tried.
      Throws:
      ErrorsException
    • createJustInTimeBinding

      private <T> BindingImpl<T> createJustInTimeBinding(Key<T> key, Errors errors, boolean jitDisabled, InjectorImpl.JitLimitation jitType) throws ErrorsException
      Returns a new just-in-time binding created by resolving key. The strategies used to create just-in-time bindings are:
      1. Internalizing Providers. If the requested binding is for Provider<T>, we delegate to the binding for T.
      2. Converting constants.
      3. ImplementedBy and ProvidedBy annotations. Only for unannotated keys.
      4. The constructor of the raw type. Only for unannotated keys.
      Throws:
      ErrorsException - if the binding cannot be created.
    • getInternalFactory

      <T> InternalFactory<? extends T> getInternalFactory(Key<T> key, Errors errors, InjectorImpl.JitLimitation jitType) throws ErrorsException
      Throws:
      ErrorsException
    • getBindings

      public Map<Key<?>,Binding<?>> getBindings()
      Description copied from interface: Injector
      Returns this injector's explicit bindings.

      The returned map does not include bindings inherited from a parent injector, should one exist. The returned map is guaranteed to iterate (for example, with its Map.entrySet() iterator) in the order of insertion. In other words, the order in which bindings appear in user Modules.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getBindings in interface Injector
    • getAllBindings

      public Map<Key<?>,Binding<?>> getAllBindings()
      Description copied from interface: Injector
      Returns a snapshot of this injector's bindings, both explicit and just-in-time. The returned map is immutable; it contains only the bindings that were present when getAllBindings() was invoked. Just-in-time bindings are only present if they have been requested at least once. Subsequent calls may return a map with additional just-in-time bindings.

      The returned map does not include bindings inherited from a parent injector, should one exist.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getAllBindings in interface Injector
    • getScopeBindings

      public Map<Class<? extends Annotation>,Scope> getScopeBindings()
      Description copied from interface: Injector
      Returns a map containing all scopes in the injector. The maps keys are scoping annotations like Singleton.class, and the values are scope instances, such as Scopes.SINGLETON. The returned map is immutable.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getScopeBindings in interface Injector
    • getTypeConverterBindings

      public Set<TypeConverterBinding> getTypeConverterBindings()
      Description copied from interface: Injector
      Returns a set containing all type converter bindings in the injector. The returned set is immutable.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getTypeConverterBindings in interface Injector
    • getElements

      public List<Element> getElements()
      Description copied from interface: Injector
      Returns the elements that make up this injector. Note that not all kinds of elements are returned.

      The returned list does not include elements inherited from a parent injector, should one exist.

      The returned list is immutable; it contains only the elements that were present when Injector.getElements() was invoked. Subsequent calls may return a list with additional elements.

      The returned list does not include data inherited from a parent injector, should one exist.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getElements in interface Injector
    • getAllMembersInjectorInjectionPoints

      public Map<TypeLiteral<?>,List<InjectionPoint>> getAllMembersInjectorInjectionPoints()
      Description copied from interface: Injector
      Returns the injection points created for calls to Injector.getMembersInjector(com.google.inject.TypeLiteral<T>) (either directly or indirectly, e.g. through Injector.injectMembers(java.lang.Object).

      This excludes any injection points from elements (which are accessible from each element via the SPI), unless Injector.getMembersInjector(com.google.inject.TypeLiteral<T>) or Injector.injectMembers(java.lang.Object) were also called for the same key.

      The returned multimap does not include data inherited from a parent injector, should one exist.

      This method is part of the Guice SPI and is intended for use by tools and extensions.

      Specified by:
      getAllMembersInjectorInjectionPoints in interface Injector
    • getParametersInjectors

      SingleParameterInjector<?>[] getParametersInjectors(List<Dependency<?>> parameters, Errors errors) throws ErrorsException
      Returns parameter injectors, or null if there are no parameters.
      Throws:
      ErrorsException
    • createParameterInjector

      <T> SingleParameterInjector<T> createParameterInjector(Dependency<T> dependency, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • injectMembers

      public void injectMembers(Object instance)
      Description copied from interface: Injector
      Injects dependencies into the fields and methods of instance. Ignores the presence or absence of an injectable constructor.

      Whenever Guice creates an instance, it performs this injection automatically (after first performing constructor injection), so if you're able to let Guice create all your objects for you, you'll never need to use this method.

      Specified by:
      injectMembers in interface Injector
      Parameters:
      instance - to inject members on
      See Also:
    • getMembersInjector

      public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral)
      Description copied from interface: Injector
      Returns the members injector used to inject dependencies into methods and fields on instances of the given type T.
      Specified by:
      getMembersInjector in interface Injector
      Specified by:
      getMembersInjector in interface Lookups
      Parameters:
      typeLiteral - type to get members injector for
      See Also:
    • getMembersInjector

      public <T> MembersInjector<T> getMembersInjector(Class<T> type)
      Description copied from interface: Injector
      Returns the members injector used to inject dependencies into methods and fields on instances of the given type T. When feasible, use Binder.getMembersInjector(TypeLiteral) instead to get increased up front error detection.
      Specified by:
      getMembersInjector in interface Injector
      Parameters:
      type - type to get members injector for
      See Also:
    • getProvider

      public <T> Provider<T> getProvider(Class<T> type)
      Description copied from interface: Injector
      Returns the provider used to obtain instances for the given type. When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.
      Specified by:
      getProvider in interface Injector
      See Also:
    • getProviderOrThrow

      <T> Provider<T> getProviderOrThrow(Dependency<T> dependency, Errors errors) throws ErrorsException
      Throws:
      ErrorsException
    • getProvider

      public <T> Provider<T> getProvider(Key<T> key)
      Description copied from interface: Injector
      Returns the provider used to obtain instances for the given injection key. When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.
      Specified by:
      getProvider in interface Injector
      Specified by:
      getProvider in interface Lookups
      See Also:
    • getInstance

      public <T> T getInstance(Key<T> key)
      Description copied from interface: Injector
      Returns the appropriate instance for the given injection key; equivalent to getProvider(key).get(). When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.
      Specified by:
      getInstance in interface Injector
    • getInstance

      public <T> T getInstance(Class<T> type)
      Description copied from interface: Injector
      Returns the appropriate instance for the given injection type; equivalent to getProvider(type).get(). When feasible, avoid using this method, in favor of having Guice inject your dependencies ahead of time.
      Specified by:
      getInstance in interface Injector
    • getLocalContext

      InternalContext getLocalContext()
      Only to be called by the SingletonScope provider.
    • enterContext

      InternalContext enterContext()
      Looks up thread local context and enters it or creates a new context if necessary.

      All callers of this are responsible for calling InternalContext.close(). Typical usage should look like:

      
       InternalContext ctx = injector.enterContext();
       try {
         ... use ctx ...
       } finally {
         ctx.close();
       }
       
    • toString

      public String toString()
      Overrides:
      toString in class Object