⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 injectorimpl.java

📁 Guice是轻量级的依赖注入框架。简而言之
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
  public <T> Provider<T> getProvider(Class<T> type) {    return getProvider(Key.get(type));  }  public <T> Provider<T> getProvider(final Key<T> key) {    final InternalFactory<? extends T> factory = getInternalFactory(null, key);    if (factory == null) {      throw new ConfigurationException(          "Missing binding to " + ErrorMessages.convert(key) + ".");    }    return new Provider<T>() {      public T get() {        return callInContext(new ContextualCallable<T>() {          public T call(InternalContext context) {            ExternalContext<?> previous = context.getExternalContext();            context.setExternalContext(                ExternalContext.newInstance(null, key, InjectorImpl.this));            try {              return factory.get(context);            }            finally {              context.setExternalContext(previous);            }          }        });      }      public String toString() {        return factory.toString();      }    };  }  public <T> T getInstance(Key<T> key) {    return getProvider(key).get();  }  public <T> T getInstance(Class<T> type) {    return getProvider(type).get();  }  final ThreadLocal<InternalContext[]> localContext      = new ThreadLocal<InternalContext[]>() {    protected InternalContext[] initialValue() {      return new InternalContext[1];    }  };  /**   * Looks up thread local context. Creates (and removes) a new context if   * necessary.   */  <T> T callInContext(ContextualCallable<T> callable) {    InternalContext[] reference = localContext.get();    if (reference[0] == null) {      reference[0] = new InternalContext(this);      try {        return callable.call(reference[0]);      }      finally {        // Only remove the context if this call created it.        reference[0] = null;      }    }    else {      // Someone else will clean up this context.      return callable.call(reference[0]);    }  }  /**   * Gets a constructor function for a given implementation class.   */  @SuppressWarnings("unchecked")  <T> ConstructorInjector<T> getConstructor(Class<T> implementation) {    return constructors.get(implementation);  }  @SuppressWarnings("unchecked")  <T> ConstructorInjector<T> getConstructor(TypeLiteral<T> implementation) {    return constructors.get(implementation.getRawType());  }  /**   * Injects a field or method in a given object.   */  interface SingleMemberInjector {    void inject(InternalContext context, Object o);  }  class MissingDependencyException extends Exception {    final Key<?> key;    final Member member;    MissingDependencyException(Key<?> key, Member member) {      this.key = key;      this.member = member;    }    void handle(ErrorHandler errorHandler) {      ErrorMessages.handleMissingBinding(errorHandler, member, key,          getNamesOfBindingAnnotations(key.getTypeLiteral()));    }  }  /**   * Map of primitive type converters.   */  static class PrimitiveConverters extends HashMap<Class<?>, Converter<?>> {    PrimitiveConverters() {      putParser(int.class);      putParser(long.class);      putParser(boolean.class);      putParser(byte.class);      putParser(short.class);      putParser(float.class);      putParser(double.class);      // Character doesn't follow the same pattern.      Converter<Character> characterConverter = new Converter<Character>() {        public Character convert(Member member, Key<Character> key,            String value) throws ConstantConversionException {          value = value.trim();          if (value.length() != 1) {            throw new ConstantConversionException(member, key, value,                "Length != 1.");          }          return value.charAt(0);        }      };      put(char.class, characterConverter);      put(Character.class, characterConverter);    }    <T> void putParser(final Class<T> primitive) {      try {        Class<?> wrapper = PRIMITIVE_COUNTERPARTS.get(primitive);        final Method parser = wrapper.getMethod(            "parse" + Strings.capitalize(primitive.getName()), String.class);        Converter<T> converter = new Converter<T>() {          @SuppressWarnings("unchecked")          public T convert(Member member, Key<T> key, String value)              throws ConstantConversionException {            try {              return (T) parser.invoke(null, value);            }            catch (IllegalAccessException e) {              throw new AssertionError(e);            }            catch (InvocationTargetException e) {              throw new ConstantConversionException(member, key, value,                  e.getTargetException());            }          }        };        put(wrapper, converter);        put(primitive, converter);      }      catch (NoSuchMethodException e) {        throw new AssertionError(e);      }    }  }  /**   * Converts a {@code String} to another type.   */  interface Converter<T> {    /**     * Converts {@code String} value.     */    T convert(Member member, Key<T> key, String value)        throws ConstantConversionException;  }  Map<Class<?>, InternalFactory<?>> implicitBindings =      new HashMap<Class<?>, InternalFactory<?>>();  /**   * Gets a factory for the specified type. Used when an explicit binding   * was not made. Uses synchronization here so it's not necessary in the   * factory itself. Returns {@code null} if the type isn't injectable.   */  <T> InternalFactory<? extends T> getImplicitBinding(Member member,      final Class<T> type, Scope scope) {    // Look for @DefaultImplementation.    ImplementedBy implementedBy =        type.getAnnotation(ImplementedBy.class);    if (implementedBy != null) {      Class<?> implementationType = implementedBy.value();      // Make sure it's not the same type. TODO: Can we check for deeper loops?      if (implementationType == type) {        errorHandler.handle(StackTraceElements.forType(type),            ErrorMessages.RECURSIVE_IMPLEMENTATION_TYPE, type);        return invalidFactory();      }      // Make sure implementationType extends type.      if (!type.isAssignableFrom(implementationType)) {        errorHandler.handle(StackTraceElements.forType(type),            ErrorMessages.NOT_A_SUBTYPE, implementationType, type);        return invalidFactory();      }      return (InternalFactory<T>) getInternalFactory(          member, Key.get(implementationType));          }    // Look for @DefaultProvider.    ProvidedBy providedBy = type.getAnnotation(ProvidedBy.class);    if (providedBy != null) {      final Class<? extends Provider<?>> providerType = providedBy.value();      // Make sure it's not the same type. TODO: Can we check for deeper loops?      if (providerType == type) {        errorHandler.handle(StackTraceElements.forType(type),            ErrorMessages.RECURSIVE_PROVIDER_TYPE, type);        return invalidFactory();      }      // TODO: Make sure the provided type extends type. We at least check      // the type at runtime below.      InternalFactory<? extends Provider<?>> providerFactory          = getInternalFactory(member, Key.get(providerType));      Key<? extends Provider<?>> providerKey = Key.get(providerType);      return (InternalFactory<T>) new BoundProviderFactory(          providerKey, providerFactory, StackTraceElements.forType(type)) {        public Object get(InternalContext context) {          Object o = super.get(context);          try {            return type.cast(o);          } catch (ClassCastException e) {            errorHandler.handle(StackTraceElements.forType(type),                ErrorMessages.SUBTYPE_NOT_PROVIDED, providerType, type);            throw new AssertionError();          }        }      };    }    // TODO: Method interceptors could actually enable us to implement    // abstract types. Should we remove this restriction?    if (Modifier.isAbstract(type.getModifiers())) {      return null;    }    // Inject the class itself.    synchronized (implicitBindings) {      @SuppressWarnings("unchecked")      InternalFactory<T> factory =          (InternalFactory<T>) implicitBindings.get(type);      if (factory != null) {        return factory;      }      // Create the factory.      ImplicitBinding<T> implicitBinding = new ImplicitBinding<T>(type);      // Scope the factory if necessary.      // If we don't have a scope from the configuration, look for one on      // the type.      if (scope == null) {        scope = Scopes.getScopeForType(type, scopes, errorHandler);      }      InternalFactory<? extends T> scoped;      if (scope != null) {        scoped = Scopes.scope(Key.get(type), this, implicitBinding, scope);      } else {        scoped = implicitBinding;      }      implicitBindings.put(type, scoped);      try {        // Look up the constructor. We do this separately from constructions to        // support circular dependencies.        ConstructorInjector<T> constructor = getConstructor(type);        implicitBinding.setConstructorInjector(constructor);      }      catch (RuntimeException e) {        // Clean up state.        implicitBindings.remove(type);        throw e;      }      catch (Throwable t) {        // Clean up state.        implicitBindings.remove(type);        throw new AssertionError(t);      }            return scoped;    }  }  static class ImplicitBinding<T> implements InternalFactory<T> {    final Class<T> implementation;    ConstructorInjector<T> constructorInjector;    ImplicitBinding(Class<T> implementation) {      this.implementation = implementation;    }    void setConstructorInjector(        ConstructorInjector<T> constructorInjector) {      this.constructorInjector = constructorInjector;    }    public T get(InternalContext context) {      return (T) constructorInjector.construct(context,          context.getExpectedType());    }  }  private static final InternalFactory<?> INVALID_FACTORY      = new InternalFactory<Object>() {    public Object get(InternalContext context) {      throw new AssertionError();    }  };  @SuppressWarnings("unchecked")  static <T> InternalFactory<T> invalidFactory() {    return (InternalFactory<T>) INVALID_FACTORY;  }  public String toString() {    return new ToStringBuilder(Injector.class)        .add("bindings", bindings)        .toString();  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -