Class InjectorImpl

    • Field Detail

      • STRING_TYPE

        public static final TypeLiteral<java.lang.String> STRING_TYPE
      • state

        final State state
      • bindingsMultimap

        final com.google.common.collect.ListMultimap<TypeLiteral<?>,​Binding<?>> bindingsMultimap
      • jitBindings

        final java.util.Map<Key<?>,​BindingImpl<?>> jitBindings
        Just-in-time binding cache. Guarded by state.lock()
      • failedJitBindings

        final java.util.Set<Key<?>> failedJitBindings
        Cache of Keys that we were unable to create JIT bindings for, so we don't keep trying. Also guarded by state.lock().
      • membersInjectorStore

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

        private final java.lang.ThreadLocal<java.lang.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.

    • Method Detail

      • index

        void index()
        Indexes bindings by type.
      • findBindingsByType

        public <T> java.util.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
      • 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​(java.lang.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​(java.lang.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
      • 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)
      • isMembersInjector

        private static boolean isMembersInjector​(Key<?> key)
        Returns true if the key type is MembersInjector (but not a subclass of MembersInjector).
      • 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
      • cleanup

        private boolean cleanup​(BindingImpl<?> binding,
                                java.util.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 & 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 java.util.Set<Dependency<?>> getInternalDependencies​(BindingImpl<?> binding)
        Safely gets the dependencies of possibly not initialized bindings.
      • createUninitializedBinding

        <T> BindingImpl<T> createUninitializedBinding​(Key<T> key,
                                                      Scoping scoping,
                                                      java.lang.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
      • 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.
      • getBindings

        public java.util.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 java.util.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 java.util.Map<java.lang.Class<? extends java.lang.annotation.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 java.util.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 java.util.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
      • injectMembers

        public void injectMembers​(java.lang.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:
        for a preferred alternative that supports checks before run time
      • 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​(java.lang.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
      • 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 java.lang.String toString()
        Overrides:
        toString in class java.lang.Object