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

📄 injectorimpl.java

📁 Guice是轻量级的依赖注入框架。简而言之
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/** * Copyright (C) 2006 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.google.inject;import com.google.inject.spi.SourceProviders;import com.google.inject.util.GuiceFastClass;import com.google.inject.util.Objects;import com.google.inject.util.ReferenceCache;import com.google.inject.util.StackTraceElements;import com.google.inject.util.Strings;import com.google.inject.util.ToStringBuilder;import java.lang.annotation.Annotation;import java.lang.reflect.AccessibleObject;import java.lang.reflect.AnnotatedElement;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Member;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import net.sf.cglib.reflect.FastClass;import net.sf.cglib.reflect.FastMethod;/** * Default {@link Injector} implementation. * * @author crazybob@google.com (Bob Lee) * @see BinderImpl */class InjectorImpl implements Injector {  /**   * Maps between primitive types and their wrappers and vice versa.   */  private static final Map<Class<?>, Class<?>> PRIMITIVE_COUNTERPARTS;  static {    Map<Class<?>, Class<?>> primitiveToWrapper =        new HashMap<Class<?>, Class<?>>() {{          put(int.class, Integer.class);          put(long.class, Long.class);          put(boolean.class, Boolean.class);          put(byte.class, Byte.class);          put(short.class, Short.class);          put(float.class, Float.class);          put(double.class, Double.class);          put(char.class, Character.class);        }};    Map<Class<?>, Class<?>> counterparts = new HashMap<Class<?>, Class<?>>();    for (Map.Entry<Class<?>, Class<?>> entry : primitiveToWrapper.entrySet()) {      Class<?> key = entry.getKey();      Class<?> value = entry.getValue();      counterparts.put(key, value);      counterparts.put(value, key);    }    PRIMITIVE_COUNTERPARTS = Collections.unmodifiableMap(counterparts);  }  private static final Map<Class<?>, Converter<?>> PRIMITIVE_CONVERTERS      = new PrimitiveConverters();  final ConstructionProxyFactory constructionProxyFactory;  final Map<Key<?>, BindingImpl<?>> bindings;  final BindingsMultimap bindingsMultimap = new BindingsMultimap();  final Map<Class<? extends Annotation>, Scope> scopes;  ErrorHandler errorHandler = new InvalidErrorHandler();  Object defaultSource = SourceProviders.UNKNOWN_SOURCE;  InjectorImpl(ConstructionProxyFactory constructionProxyFactory,      Map<Key<?>, BindingImpl<?>> bindings,      Map<Class<? extends Annotation>, Scope> scopes) {    this.constructionProxyFactory = constructionProxyFactory;    this.bindings = bindings;    this.scopes = scopes;  }  /**   * Indexes bindings by type.   */  void index() {    for (BindingImpl<?> binding : bindings.values()) {      index(binding);    }  }  <T> void index(BindingImpl<T> binding) {    bindingsMultimap.put(binding.getKey().getTypeLiteral(), binding);  }  // not test-covered  public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {    return Collections.<Binding<T>>unmodifiableList(        bindingsMultimap.getAll(type));  }  // not test-covered  <T> List<String> getNamesOfBindingAnnotations(TypeLiteral<T> type) {    List<String> names = new ArrayList<String>();    for (Binding<T> binding : findBindingsByType(type)) {      Key<T> key = binding.getKey();      if (!key.hasAnnotationType()) {        names.add("[no annotation]");      } else {        names.add(key.getAnnotationName());      }    }    return names;  }  /**   * This is only used during Injector building.   */  void withDefaultSource(Object defaultSource, Runnable runnable) {    Object previous = this.defaultSource;    this.defaultSource = defaultSource;    try {      runnable.run();    }    finally {      this.defaultSource = previous;    }  }  void setErrorHandler(ErrorHandler errorHandler) {    this.errorHandler = errorHandler;  }  <T> InternalFactory<? extends T> getInternalFactory(      final Member member, Key<T> key) {    // TODO: Clean up unchecked type warnings.    // Do we have a factory for the specified type and name?    BindingImpl<T> binding = getBinding(key);    if (binding != null) {      return binding.getInternalFactory();    }    Class<? super T> rawType = key.getTypeLiteral().getRawType();    // Handle cases where T is a Provider<?>.    if (rawType.equals(Provider.class)) {      Type providerType = key.getTypeLiteral().getType();      if (!(providerType instanceof ParameterizedType)) {        // Raw Provider.        return null;      }      Type entryType          = ((ParameterizedType) providerType).getActualTypeArguments()[0];      try {        final Provider<?> provider = getProvider(key.ofType(entryType));        return new InternalFactory<T>() {          @SuppressWarnings("unchecked")          public T get(InternalContext context) {            return (T) provider;          }        };      }      catch (ConfigurationException e) {        // Look for a factory bound to a key without annotation attributes if        // necessary.        if (key.hasAttributes()) {          return getInternalFactory(member, key.withoutAttributes());        }        // End of the road.        ErrorMessages.handleMissingBinding(errorHandler, member, key,            getNamesOfBindingAnnotations(key.getTypeLiteral()));        return invalidFactory();      }    }    // Auto[un]box primitives.    Class<?> primitiveCounterpart        = PRIMITIVE_COUNTERPARTS.get(rawType);    if (primitiveCounterpart != null) {      BindingImpl<?> counterpartBinding          = getBinding(key.ofType(primitiveCounterpart));      if (counterpartBinding != null) {        return (InternalFactory<? extends T>)            counterpartBinding.getInternalFactory();      }    }    // TODO: Should we try to convert from a String first, or should we look    // for a binding to the annotation type sans attributes? Right now, we    // convert from a String.    // Can we convert from a String constant?    Key<String> stringKey = key.ofType(String.class);    BindingImpl<String> stringBinding = getBinding(stringKey);    if (stringBinding != null && stringBinding.isConstant()) {      // We don't need do pass in an InternalContext because we know this is      // a ConstantFactory which will not use it.      String value = stringBinding.getInternalFactory().get(null);      // TODO: Generalize everything below here and enable users to plug in      // their own converters.      // Do we need a primitive?      Converter<T> converter = (Converter<T>) PRIMITIVE_CONVERTERS.get(rawType);      if (converter != null) {        try {          T t = converter.convert(member, key, value);          return new ConstantFactory<T>(t);        }        catch (ConstantConversionException e) {          return handleConstantConversionError(              member, stringBinding, rawType, e);        }      }      // Do we need an enum?      if (Enum.class.isAssignableFrom(rawType)) {        T t;        try {          t = (T) Enum.valueOf((Class) rawType, value);        }        catch (IllegalArgumentException e) {          return handleConstantConversionError(              member, stringBinding, rawType, e);        }        return new ConstantFactory<T>(t);      }      // Do we need a class?      if (rawType == Class.class) {        try {          // TODO: Make sure we use the right classloader.          return new ConstantFactory<T>((T) Class.forName(value));        }        catch (ClassNotFoundException e) {          return handleConstantConversionError(              member, stringBinding, rawType, e);        }      }    }    // Don't try to inject primitives, arrays, or enums.    int modifiers = rawType.getModifiers();    if (rawType.isArray() || rawType.isEnum() || rawType.isPrimitive()) {      // Look for a factory bound to a key without annotation attributes if      // necessary.      if (key.hasAttributes()) {        return getInternalFactory(member, key.withoutAttributes());      }      return null;    }    // We don't want to implicitly inject a member if we have a binding    // annotation.    if (key.hasAnnotationType()) {      // Look for a factory bound to a key without annotation attributes if      // necessary.      if (key.hasAttributes()) {        return getInternalFactory(member, key.withoutAttributes());      }      return null;    }    // Last resort: inject the type itself.    if (member != null) {      // If we're injecting into a member, include it in the error messages.      final ErrorHandler previous = this.errorHandler;      this.errorHandler = new AbstractErrorHandler() {        public void handle(Object source, String message) {          previous.handle(source, "Error while injecting at "              + StackTraceElements.forMember(member) + ": " + message);        }      };      try {        // note: intelliJ thinks this cast is superfluous, but is it?        return (InternalFactory<? extends T>) getImplicitBinding(member,            rawType, null);      }      finally {        this.errorHandler = previous;      }    }    // note: intelliJ thinks this cast is superfluous, but is it?    return (InternalFactory<? extends T>) getImplicitBinding(member, rawType,        null);  }  private <T> InternalFactory<T> handleConstantConversionError(      Member member, Binding<String> stringBinding, Class<?> rawType,      Exception e) {    errorHandler.handle(        StackTraceElements.forMember(member),        ErrorMessages.CONSTANT_CONVERSION_ERROR,        stringBinding.getSource(),        rawType,        e.getMessage());    return invalidFactory();  }  /**   * Field and method injectors.   */  final Map<Class<?>, List<SingleMemberInjector>> injectors      = new ReferenceCache<Class<?>, List<SingleMemberInjector>>() {    protected List<SingleMemberInjector> create(Class<?> key) {      List<SingleMemberInjector> injectors          = new ArrayList<SingleMemberInjector>();      addInjectors(key, injectors);      return injectors;    }  };  /**   * Recursively adds injectors for fields and methods from the given class to   * the given list. Injects parent classes before sub classes.   */  void addInjectors(Class clazz, List<SingleMemberInjector> injectors) {    if (clazz == Object.class) {      return;

⌨️ 快捷键说明

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