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

📄 bindingbuilderimpl.java

📁 Guice是轻量级的依赖注入框架。简而言之
💻 JAVA
字号:
/* * Copyright (C) 2007 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.BinderImpl.CreationListener;import com.google.inject.binder.ScopedBindingBuilder;import com.google.inject.binder.AnnotatedBindingBuilder;import com.google.inject.util.Annotations;import com.google.inject.util.Objects;import com.google.inject.util.StackTraceElements;import com.google.inject.util.ToStringBuilder;import java.lang.annotation.Annotation;import java.util.logging.Level;import java.util.logging.Logger;/** * Binds a {@link com.google.inject.Key} to an implementation in a given scope. */class BindingBuilderImpl<T> implements AnnotatedBindingBuilder<T> {  private static final Logger logger      = Logger.getLogger(BindingBuilderImpl.class.getName());  final Object source;  Key<T> key;  InternalFactory<? extends T> factory;  T instance;  Scope scope;  boolean preload = false;  private BinderImpl binder;  BindingBuilderImpl(BinderImpl binder, Key<T> key, Object source) {    this.binder = binder;    this.key = Objects.nonNull(key, "key");    this.source = source;  }  Object getSource() {    return source;  }  Key<T> getKey() {    return key;  }  public BindingBuilderImpl<T> annotatedWith(      Class<? extends Annotation> annotationType) {    if (this.key.hasAnnotationType()) {      binder.addError(source, ErrorMessages.ANNOTATION_ALREADY_SPECIFIED);    } else {      boolean retainedAtRuntime =          Annotations.isRetainedAtRuntime(annotationType);      boolean bindingAnnotation = Key.isBindingAnnotation(annotationType);      if (!retainedAtRuntime) {        binder.addError(StackTraceElements.forType(annotationType),            ErrorMessages.MISSING_RUNTIME_RETENTION, binder.source());      }      if (!bindingAnnotation) {        binder.addError(StackTraceElements.forType(annotationType),            ErrorMessages.MISSING_BINDING_ANNOTATION, binder.source());      }      if (retainedAtRuntime && bindingAnnotation) {        this.key = Key.get(this.key.getTypeLiteral(), annotationType);      }    }    return this;  }  public BindingBuilderImpl<T> annotatedWith(Annotation annotation) {    if (this.key.hasAnnotationType()) {      binder.addError(source, ErrorMessages.ANNOTATION_ALREADY_SPECIFIED);    } else {      Class<? extends Annotation> annotationType = annotation.annotationType();      boolean retainedAtRuntime =          Annotations.isRetainedAtRuntime(annotationType);      boolean bindingAnnotation = Key.isBindingAnnotation(annotationType);      if (!retainedAtRuntime) {        binder.addError(StackTraceElements.forType(annotationType),            ErrorMessages.MISSING_RUNTIME_RETENTION, binder.source());      }      if (!bindingAnnotation) {        binder.addError(StackTraceElements.forType(annotationType),            ErrorMessages.MISSING_BINDING_ANNOTATION, binder.source());      }      if (retainedAtRuntime && bindingAnnotation) {        this.key = Key.get(this.key.getTypeLiteral(), annotation);      }    }    return this;  }  public ScopedBindingBuilder to(Class<? extends T> implementation) {    return to(TypeLiteral.get(implementation));  }  public ScopedBindingBuilder to(TypeLiteral<? extends T> implementation) {    return to(Key.get(implementation));  }  public ScopedBindingBuilder to(Key<? extends T> targetKey) {    ensureImplementationIsNotSet();    if (key.equals(targetKey)) {      binder.addError(source, ErrorMessages.RECURSIVE_BINDING);    }    final FactoryProxy<? extends T> factoryProxy =        new FactoryProxy<T>(key, targetKey, source);    this.factory = factoryProxy;    binder.creationListeners.add(factoryProxy);    return this;  }  public void toInstance(T instance) {    ensureImplementationIsNotSet();    this.instance = Objects.nonNull(instance, "instance");    this.factory = new ConstantFactory<T>(instance);    registerInstanceForInjection(instance);    if (this.scope != null) {      binder.addError(source, ErrorMessages.SINGLE_INSTANCE_AND_SCOPE);    }  }  /**   * Binds to instances from the given factory.   */  BindingBuilderImpl<T> to(InternalFactory<? extends T> factory) {    ensureImplementationIsNotSet();    this.factory = factory;    return this;  }  public ScopedBindingBuilder toProvider(Provider<? extends T> provider) {    ensureImplementationIsNotSet();    this.factory = new InternalFactoryToProviderAdapter<T>(provider, source);    registerInstanceForInjection(provider);    return this;  }  public BindingBuilderImpl<T> toProvider(      Class<? extends Provider<? extends T>> providerType) {    return toProvider(Key.get(providerType));  }  public BindingBuilderImpl<T> toProvider(      Key<? extends Provider<? extends T>> providerKey) {    ensureImplementationIsNotSet();    final BoundProviderFactory<T> boundProviderFactory =        new BoundProviderFactory<T>(providerKey, source);    binder.creationListeners.add(boundProviderFactory);    this.factory = boundProviderFactory;    return this;  }  /**   * Adds an error message if the implementation has already been bound.   */  private void ensureImplementationIsNotSet() {    if (factory != null) {      binder.addError(source, ErrorMessages.IMPLEMENTATION_ALREADY_SET);    }  }  public void in(Class<? extends Annotation> scopeAnnotation) {    // this method not test-covered    ensureScopeNotSet();    // We could defer this lookup to when we create the Injector, but this    // is fine for now.    this.scope = binder.scopes.get(        Objects.nonNull(scopeAnnotation, "scope annotation"));    if (this.scope == null) {      binder.addError(source, ErrorMessages.SCOPE_NOT_FOUND,          "@" + scopeAnnotation.getSimpleName());    }  }  public void in(Scope scope) {    ensureScopeNotSet();    this.scope = Objects.nonNull(scope, "scope");  }  private void ensureScopeNotSet() {    // Scoping isn't allowed when we have only one instance.    if (this.instance != null) {      binder.addError(source, ErrorMessages.SINGLE_INSTANCE_AND_SCOPE);      return;    }    if (this.scope != null) {      binder.addError(source, ErrorMessages.SCOPE_ALREADY_SET);    }  }  public void asEagerSingleton() {    in(Scopes.SINGLETON);    this.preload = true;  }  boolean shouldPreload() {    return preload;  }  InternalFactory<? extends T> getInternalFactory(InjectorImpl injector) {    if (this.factory == null && !key.hasAnnotationType()) {      // Try an implicit binding.      final ImplicitImplementation<T> implicitImplementation =          new ImplicitImplementation<T>(key, scope, source);      binder.creationListeners.add(implicitImplementation);      // We need to record the scope. If it's singleton, we'll preload in prod.      if (this.scope == null) {        // We can ignore errors because the error will already have been        // recorded.        this.scope = Scopes.getScopeForType(            key.getTypeLiteral().getRawType(), binder.scopes, IGNORE_ERRORS);      }      return implicitImplementation;    }    return Scopes.scope(this.key, injector, this.factory, scope);  }  boolean isSingletonScoped() {    return this.scope == Scopes.SINGLETON;  }  void registerInstanceForInjection(final Object o) {    binder.instanceInjectors.add(new CreationListener() {      public void notify(InjectorImpl injector) {        try {          injector.injectMembers(o);        }        catch (Exception e) {          String className = e.getClass().getSimpleName();          String message = ErrorMessages.getRootMessage(e);          String logMessage = String.format(              ErrorMessages.ERROR_INJECTING_MEMBERS, o, message);          logger.log(Level.INFO, logMessage, e);          binder.addError(source, ErrorMessages.ERROR_INJECTING_MEMBERS_SEE_LOG,              className, o, message);        }      }    });  }  /**   * A placeholder which enables us to swap in the real factory once the   * container is created.   */  private static class FactoryProxy<T> implements InternalFactory<T>,      CreationListener {    private final Key<T> key;    private final Key<? extends T> targetKey;    private final Object source;    InternalFactory<? extends T> targetFactory;    FactoryProxy(Key<T> key, Key<? extends T> targetKey, Object source) {      this.key = key;      this.targetKey = targetKey;      this.source = source;    }    public void notify(final InjectorImpl injector) {      injector.withDefaultSource(source, new Runnable() {        public void run() {          targetFactory = injector.getInternalFactory(null, targetKey);        }      });    }    public T get(InternalContext context) {      return targetFactory.get(context);    }    public String toString() {      return new ToStringBuilder(FactoryProxy.class)          .add("key", key)          .add("provider", targetFactory)          .toString();    }  }  private static class ImplicitImplementation<T> implements InternalFactory<T>,      CreationListener {    private final Key<T> key;    private final Object source;    private final Scope scope;    InternalFactory<? extends T> implicitFactory;    ImplicitImplementation(Key<T> key, Scope scope, Object source) {      this.key = key;      this.scope = scope;      this.source = source;    }    public void notify(final InjectorImpl injector) {      injector.withDefaultSource(source, new Runnable() {        public void run() {          implicitFactory = injector.getImplicitBinding(null,              (Class) key.getTypeLiteral().getRawType(), scope);        }      });    }    public T get(InternalContext context) {      return implicitFactory.get(context);    }    public String toString() {      return new ToStringBuilder(FactoryProxy.class)          .add("key", key)          .add("provider", implicitFactory)          .toString();    }  }  static ErrorHandler IGNORE_ERRORS = new ErrorHandler() {    public void handle(Object source, String message) {}    public void handle(Object source, String message, Object... arguments) {}  };}

⌨️ 快捷键说明

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