blob: 7bdaa4f9b2374e34fc5b2c6db738bf3c76047c9d [file] [log] [blame]
crazybobleeabc4dd02007-02-01 01:44:36 +00001/**
2 * Copyright (C) 2006 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
crazyboblee63b592b2007-01-25 02:45:24 +000016
17package com.google.inject;
18
limpbizkit5ae41eb2009-06-06 17:51:27 +000019import com.google.inject.internal.InjectorBuilder;
limpbizkit76c24b12008-12-25 04:32:41 +000020
crazyboblee63b592b2007-01-25 02:45:24 +000021/**
limpbizkit76c24b12008-12-25 04:32:41 +000022 * Built-in scope implementations.
crazyboblee63b592b2007-01-25 02:45:24 +000023 *
24 * @author crazybob@google.com (Bob Lee)
25 */
crazyboblee68d2f4b2007-02-07 18:47:24 +000026public class Scopes {
27
crazybobleef33d23e2007-02-12 04:17:48 +000028 private Scopes() {}
crazyboblee63b592b2007-01-25 02:45:24 +000029
30 /**
crazyboblee61257a82007-03-03 00:23:40 +000031 * One instance per {@link Injector}. Also see {@code @}{@link Singleton}.
crazyboblee63b592b2007-01-25 02:45:24 +000032 */
kevinb9na2915a92007-02-28 06:20:30 +000033 public static final Scope SINGLETON = new Scope() {
crazybobleebd9544e2007-02-25 20:32:11 +000034 public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
35 return new Provider<T>() {
crazybobleee5fbbb02007-02-05 07:00:27 +000036
37 private volatile T instance;
38
crazybobleef33d23e2007-02-12 04:17:48 +000039 // DCL on a volatile is safe as of Java 5, which we obviously require.
kevinb9n6a565c72007-02-11 01:58:33 +000040 @SuppressWarnings("DoubleCheckedLocking")
crazybobleee5fbbb02007-02-05 07:00:27 +000041 public T get() {
crazybobleee5fbbb02007-02-05 07:00:27 +000042 if (instance == null) {
kevinb9na99dca72007-02-11 04:48:57 +000043 /*
44 * Use a pretty coarse lock. We don't want to run into deadlocks
45 * when two threads try to load circularly-dependent objects.
46 * Maybe one of these days we will identify independent graphs of
47 * objects and offer to load them in parallel.
48 */
limpbizkit5ae41eb2009-06-06 17:51:27 +000049 synchronized (InjectorBuilder.class) {
crazybobleee5fbbb02007-02-05 07:00:27 +000050 if (instance == null) {
51 instance = creator.get();
52 }
53 }
54 }
55 return instance;
56 }
57
58 public String toString() {
kevinb9nda11d0d2007-04-20 15:58:38 +000059 return String.format("%s[%s]", creator, SINGLETON);
crazybobleee5fbbb02007-02-05 07:00:27 +000060 }
61 };
62 }
crazybobleef33d23e2007-02-12 04:17:48 +000063
limpbizkitc9465f92008-05-31 19:01:54 +000064 @Override public String toString() {
kevinb9na2915a92007-02-28 06:20:30 +000065 return "Scopes.SINGLETON";
crazybobleef33d23e2007-02-12 04:17:48 +000066 }
crazyboblee68d2f4b2007-02-07 18:47:24 +000067 };
crazybobleef33d23e2007-02-12 04:17:48 +000068
69 /**
kevinb9nb6054822007-03-19 03:17:47 +000070 * No scope; the same as not applying any scope at all. Each time the
71 * Injector obtains an instance of an object with "no scope", it injects this
72 * instance then immediately forgets it. When the next request for the same
73 * binding arrives it will need to obtain the instance over again.
74 *
75 * <p>This exists only in case a class has been annotated with a scope
76 * annotation such as {@link Singleton @Singleton}, and you need to override
77 * this to "no scope" in your binding.
limpbizkitc489adf2008-11-18 07:01:33 +000078 *
79 * @since 2.0
kevinb9nb6054822007-03-19 03:17:47 +000080 */
81 public static final Scope NO_SCOPE = new Scope() {
82 public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
83 return unscoped;
84 }
limpbizkitc9465f92008-05-31 19:01:54 +000085 @Override public String toString() {
kevinb9nb6054822007-03-19 03:17:47 +000086 return "Scopes.NO_SCOPE";
87 }
88 };
kevinb9na99dca72007-02-11 04:48:57 +000089}