/*
 * 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.internal.CircularDependencyProxy;
import com.google.inject.internal.LinkedBindingImpl;
import com.google.inject.internal.SingletonScope;
import com.google.inject.spi.BindingScopingVisitor;
import com.google.inject.spi.ExposedBinding;
import java.lang.annotation.Annotation;

Built-in scope implementations.
Author:crazybob@google.com (Bob Lee)
/** * Built-in scope implementations. * * @author crazybob@google.com (Bob Lee) */
public class Scopes { private Scopes() {}
One instance per Injector. Also see @Singleton.
/** One instance per {@link Injector}. Also see {@code @}{@link Singleton}. */
public static final Scope SINGLETON = new SingletonScope();
No scope; the same as not applying any scope at all. Each time the Injector obtains an instance of an object with "no scope", it injects this instance then immediately forgets it. When the next request for the same binding arrives it will need to obtain the instance over again.

This exists only in case a class has been annotated with a scope annotation such as @Singleton, and you need to override this to "no scope" in your binding.

Since:2.0
/** * No scope; the same as not applying any scope at all. Each time the Injector obtains an instance * of an object with "no scope", it injects this instance then immediately forgets it. When the * next request for the same binding arrives it will need to obtain the instance over again. * * <p>This exists only in case a class has been annotated with a scope annotation such as {@link * Singleton @Singleton}, and you need to override this to "no scope" in your binding. * * @since 2.0 */
public static final Scope NO_SCOPE = new Scope() { @Override public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) { return unscoped; } @Override public String toString() { return "Scopes.NO_SCOPE"; } }; private static final BindingScopingVisitor<Boolean> IS_SINGLETON_VISITOR = new BindingScopingVisitor<Boolean>() { @Override public Boolean visitNoScoping() { return false; } @Override public Boolean visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) { return scopeAnnotation == Singleton.class || scopeAnnotation == javax.inject.Singleton.class; } @Override public Boolean visitScope(Scope scope) { return scope == Scopes.SINGLETON; } @Override public Boolean visitEagerSingleton() { return true; } };
Returns true if binding is singleton-scoped. If the binding is a linked key binding and belongs to an injector (ie. it was retrieved via Injector.getBinding()), then this method will also true if the target binding is singleton-scoped.
Since:3.0
/** * Returns true if {@code binding} is singleton-scoped. If the binding is a {@link * com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (ie. it * was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will * also true if the target binding is singleton-scoped. * * @since 3.0 */
public static boolean isSingleton(Binding<?> binding) { do { boolean singleton = binding.acceptScopingVisitor(IS_SINGLETON_VISITOR); if (singleton) { return true; } if (binding instanceof LinkedBindingImpl) { LinkedBindingImpl<?> linkedBinding = (LinkedBindingImpl) binding; Injector injector = linkedBinding.getInjector(); if (injector != null) { binding = injector.getBinding(linkedBinding.getLinkedKey()); continue; } } else if (binding instanceof ExposedBinding) { ExposedBinding<?> exposedBinding = (ExposedBinding) binding; Injector injector = exposedBinding.getPrivateElements().getInjector(); if (injector != null) { binding = injector.getBinding(exposedBinding.getKey()); continue; } } return false; } while (true); }
Returns true if binding has the given scope. If the binding is a linked key binding and belongs to an injector (ie. it was retrieved via Injector.getBinding()), then this method will also true if the target binding has the given scope.
Params:
  • binding – binding to check
  • scope – scope implementation instance
  • scopeAnnotation – scope annotation class
Since:4.0
/** * Returns true if {@code binding} has the given scope. If the binding is a {@link * com.google.inject.spi.LinkedKeyBinding linked key binding} and belongs to an injector (ie. it * was retrieved via {@link Injector#getBinding Injector.getBinding()}), then this method will * also true if the target binding has the given scope. * * @param binding binding to check * @param scope scope implementation instance * @param scopeAnnotation scope annotation class * @since 4.0 */
public static boolean isScoped( Binding<?> binding, final Scope scope, final Class<? extends Annotation> scopeAnnotation) { do { boolean matches = binding.acceptScopingVisitor( new BindingScopingVisitor<Boolean>() { @Override public Boolean visitNoScoping() { return false; } @Override public Boolean visitScopeAnnotation(Class<? extends Annotation> visitedAnnotation) { return visitedAnnotation == scopeAnnotation; } @Override public Boolean visitScope(Scope visitedScope) { return visitedScope == scope; } @Override public Boolean visitEagerSingleton() { return false; } }); if (matches) { return true; } if (binding instanceof LinkedBindingImpl) { LinkedBindingImpl<?> linkedBinding = (LinkedBindingImpl) binding; Injector injector = linkedBinding.getInjector(); if (injector != null) { binding = injector.getBinding(linkedBinding.getLinkedKey()); continue; } } else if (binding instanceof ExposedBinding) { ExposedBinding<?> exposedBinding = (ExposedBinding) binding; Injector injector = exposedBinding.getPrivateElements().getInjector(); if (injector != null) { binding = injector.getBinding(exposedBinding.getKey()); continue; } } return false; } while (true); }
Returns true if the object is a proxy for a circular dependency, constructed by Guice because it encountered a circular dependency. Scope implementations should be careful to not cache circular proxies, because the proxies are not intended for general purpose use. (They are designed just to fulfill the immediate injection, not all injections. Caching them can lead to IllegalArgumentExceptions or ClassCastExceptions.)
Since:4.0
/** * Returns true if the object is a proxy for a circular dependency, constructed by Guice because * it encountered a circular dependency. Scope implementations should be careful to <b>not cache * circular proxies</b>, because the proxies are not intended for general purpose use. (They are * designed just to fulfill the immediate injection, not all injections. Caching them can lead to * IllegalArgumentExceptions or ClassCastExceptions.) * * @since 4.0 */
public static boolean isCircularProxy(Object object) { return object instanceof CircularDependencyProxy; } }