Home | History | Annotate | Download | only in spi
      1 /*
      2  * Copyright (C) 2011 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.google.inject.spi;
     18 
     19 import com.google.inject.Binding;
     20 import com.google.inject.Provider;
     21 import com.google.inject.Scope;
     22 
     23 /**
     24  * Listens for provisioning of objects. Useful for gathering timing information about provisioning,
     25  * post-provision initialization, and more.
     26  *
     27  * @author sameb (at) google.com (Sam Berlin)
     28  * @since 4.0
     29  */
     30 public interface ProvisionListener {
     31 
     32   /**
     33    * Invoked by Guice when an object requires provisioning. Provisioning occurs when Guice locates
     34    * and injects the dependencies for a binding. For types bound to a Provider, provisioning
     35    * encapsulates the {@link Provider#get} method. For toInstance or constant bindings, provisioning
     36    * encapsulates the injecting of {@literal @}{@code Inject}ed fields or methods. For other types,
     37    * provisioning encapsulates the construction of the object. If a type is bound within a {@link
     38    * Scope}, provisioning depends on the scope. Types bound in Singleton scope will only be
     39    * provisioned once. Types bound in no scope will be provisioned every time they are injected.
     40    * Other scopes define their own behavior for provisioning.
     41    *
     42    * <p>To perform the provision, call {@link ProvisionInvocation#provision()}. If you do not
     43    * explicitly call provision, it will be automatically done after this method returns. It is an
     44    * error to call provision more than once.
     45    */
     46   <T> void onProvision(ProvisionInvocation<T> provision);
     47 
     48   /**
     49    * Encapsulates a single act of provisioning.
     50    *
     51    * @since 4.0
     52    */
     53   public abstract static class ProvisionInvocation<T> {
     54 
     55     /**
     56      * Returns the Binding this is provisioning.
     57      *
     58      * <p>You must not call {@link Provider#get()} on the provider returned by {@link
     59      * Binding#getProvider}, otherwise you will get confusing error messages.
     60      */
     61     public abstract Binding<T> getBinding();
     62 
     63     /** Performs the provision, returning the object provisioned. */
     64     public abstract T provision();
     65 
     66     /**
     67      * Returns the dependency chain that led to this object being provisioned.
     68      *
     69      * @deprecated This method is planned for removal in Guice 4.4.  Some use cases can be replaced
     70      * by inferring the current chain via ThreadLocals in the listener, other use cases can use
     71      * the static dependency graph.  For example,
     72      * <pre>{@code
     73      *   bindListener(Matchers.any(), new MyListener());
     74      *   ...
     75      *
     76      *   private static final class MyListener implements ProvisionListener {
     77      *     private final ThreadLocal<ArrayDeque<Binding<?>>> bindingStack =
     78      *         new ThreadLocal<ArrayDeque<Binding<?>>>() {
     79      *           {@literal @}Override protected ArrayDeque<Binding<?>> initialValue() {
     80      *             return new ArrayDeque<>();
     81      *           }
     82      *         };
     83      *     {@literal @}Override public <T> void onProvision(ProvisionInvocation<T> invocation) {
     84      *       bindingStack.get().push(invocation.getBinding());
     85      *       try {
     86      *         invocation.provision();
     87      *       } finally {
     88      *         bindingStack.get().pop();
     89      *       }
     90      *       // Inspect the binding stack...
     91      *     }
     92      *   }
     93      *
     94      * }<pre>
     95      *
     96      * In this example the bindingStack thread local will contain a data structure that is very
     97      * similar to the data returned by this list.  The main differences are that linked keys are
     98      * not in the stack, but such edges do exist in the static dependency graph (inspectable via
     99      * {@link HasDependencies#getDependencies()}), so you could infer some of the missing edges..
    100      */
    101     @Deprecated
    102     public abstract java.util.List<DependencyAndSource> getDependencyChain();
    103 
    104   }
    105 }
    106