Pulled up some anonymous inner classes. Hopefully the CB will be eligible for garbage collection after startup. I'll have to test this theory later.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@45 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index a6f7cd1..b5bb567 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -93,8 +93,8 @@
static final Scope DEFAULT_SCOPE = new Scope() {
public <T> Factory<T> scope(Key<T> key, Factory<T> creator) {
- // We actually optimize around this.
- throw new UnsupportedOperationException();
+ // We special case optimize default scope, so this never actually runs.
+ throw new AssertionError();
}
};
@@ -405,7 +405,8 @@
}
}
- private void createConstantBindings(HashMap<Key<?>, InternalFactory<?>> factories) {
+ private void createConstantBindings(
+ HashMap<Key<?>, InternalFactory<?>> factories) {
for (ConstantBindingBuilder builder : constantBindingBuilders) {
if (builder.hasValue()) {
Key<?> key = builder.getKey();
@@ -498,7 +499,7 @@
public <I extends T> BindingBuilder<T> to(TypeLiteral<I> implementation) {
ensureImplementationIsNotSet();
validate(source, implementation.getRawType());
- this.factory = new DefaultFactory<I>(implementation);
+ this.factory = new DefaultFactory<I>(key, implementation);
setScopeFromType(implementation.getRawType());
return this;
}
@@ -517,15 +518,7 @@
final ContextualFactory<? extends T> factory) {
ensureImplementationIsNotSet();
- this.factory = new InternalFactory<T>() {
- public T get(InternalContext context) {
- return factory.get(context.getExternalContext());
- }
-
- public String toString() {
- return factory.toString();
- }
- };
+ this.factory = new InternalToContextualFactoryAdapter<T>(factory);
return this;
}
@@ -535,17 +528,7 @@
*/
public BindingBuilder<T> to(final Factory<? extends T> factory) {
ensureImplementationIsNotSet();
-
- this.factory = new InternalFactory<T>() {
- public T get(InternalContext context) {
- return factory.get();
- }
-
- public String toString() {
- return factory.toString();
- }
- };
-
+ this.factory = new InternalFactoryToFactoryAdapter<T>(factory);
return this;
}
@@ -620,66 +603,44 @@
return this.factory;
}
- // TODO: This is a little hairy.
- final InternalFactory<? extends T> internalFactory = this.factory;
- final Factory<T> factory = scope.scope(this.key, new Factory<T>() {
- public T get() {
- return container.callInContext(
- new ContainerImpl.ContextualCallable<T>() {
- public T call(InternalContext context) {
- return internalFactory.get(context);
- }
- });
- }
-
- public String toString() {
- return internalFactory.toString();
- }
- });
-
- return new InternalFactory<T>() {
- public T get(InternalContext context) {
- return factory.get();
- }
-
- public String toString() {
- return factory.toString();
- }
- };
+ Factory<T> scoped = scope.scope(this.key,
+ new FactoryToInternalFactoryAdapter<T>(container, this.factory));
+ return new InternalFactoryToFactoryAdapter<T>(scoped);
}
boolean isInContainerScope() {
return this.scope == ContainerScope.INSTANCE;
}
+ }
- /**
- * Injects new instances of the specified implementation class.
- */
- private class DefaultFactory<I extends T> implements InternalFactory<I> {
+ /**
+ * Injects new instances of the specified implementation class.
+ */
+ private static class DefaultFactory<T> implements InternalFactory<T> {
- volatile ContainerImpl.ConstructorInjector<I> constructor;
+ volatile ContainerImpl.ConstructorInjector<T> constructor;
- private final TypeLiteral<I> implementation;
+ private final TypeLiteral<T> implementation;
+ private final Key<? super T> key;
- public DefaultFactory(TypeLiteral<I> implementation) {
- // TODO: Ensure this is a concrete implementation.
- this.implementation = implementation;
+ public DefaultFactory(Key<? super T> key, TypeLiteral<T> implementation) {
+ this.key = key;
+ this.implementation = implementation;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T get(InternalContext context) {
+ if (constructor == null) {
+ // This unnecessary cast is a workaround for an annoying compiler
+ // bug I keep running into.
+ Object c = context.getContainerImpl().getConstructor(implementation);
+ this.constructor = (ContainerImpl.ConstructorInjector<T>) c;
}
+ return (T) constructor.construct(context, key.getRawType());
+ }
- @SuppressWarnings("unchecked")
- public I get(InternalContext context) {
- if (constructor == null) {
- // This unnecessary cast is a workaround for an annoying compiler
- // bug I keep running into.
- Object c = context.getContainerImpl().getConstructor(implementation);
- this.constructor = (ContainerImpl.ConstructorInjector<I>) c;
- }
- return (I) constructor.construct(context, key.getRawType());
- }
-
- public String toString() {
- return implementation.toString();
- }
+ public String toString() {
+ return implementation.toString();
}
}
diff --git a/src/com/google/inject/ContainerCreationException.java b/src/com/google/inject/ContainerCreationException.java
index fbbdc47..1cbf14f 100644
--- a/src/com/google/inject/ContainerCreationException.java
+++ b/src/com/google/inject/ContainerCreationException.java
@@ -4,7 +4,8 @@
/**
* Thrown when errors occurs while creating a {@link Container}. Includes a
- * list of encountered errors.
+ * list of encountered errors. Typically, a client should catch this exception,
+ * log it, and stop execution.
*
* @author crazybob@google.com (Bob Lee)
*/
diff --git a/src/com/google/inject/FactoryToInternalFactoryAdapter.java b/src/com/google/inject/FactoryToInternalFactoryAdapter.java
new file mode 100644
index 0000000..a7bca2b
--- /dev/null
+++ b/src/com/google/inject/FactoryToInternalFactoryAdapter.java
@@ -0,0 +1,32 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+*/
+class FactoryToInternalFactoryAdapter<T> implements Factory<T> {
+
+ private final ContainerImpl container;
+
+ private final InternalFactory<? extends T> internalFactory;
+
+ public FactoryToInternalFactoryAdapter(ContainerImpl container,
+ InternalFactory<? extends T> internalFactory) {
+ this.container = container;
+ this.internalFactory = internalFactory;
+ }
+
+ public T get() {
+ return container.callInContext(
+ new ContainerImpl.ContextualCallable<T>() {
+ public T call(InternalContext context) {
+ return internalFactory.get(context);
+ }
+ });
+ }
+
+ public String toString() {
+ return internalFactory.toString();
+ }
+}
diff --git a/src/com/google/inject/InternalFactoryToFactoryAdapter.java b/src/com/google/inject/InternalFactoryToFactoryAdapter.java
new file mode 100644
index 0000000..318be41
--- /dev/null
+++ b/src/com/google/inject/InternalFactoryToFactoryAdapter.java
@@ -0,0 +1,23 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+*/
+class InternalFactoryToFactoryAdapter<T> implements InternalFactory<T> {
+
+ private final Factory<? extends T> factory;
+
+ public InternalFactoryToFactoryAdapter(Factory<? extends T> factory) {
+ this.factory = factory;
+ }
+
+ public T get(InternalContext context) {
+ return factory.get();
+ }
+
+ public String toString() {
+ return factory.toString();
+ }
+}
diff --git a/src/com/google/inject/InternalToContextualFactoryAdapter.java b/src/com/google/inject/InternalToContextualFactoryAdapter.java
new file mode 100644
index 0000000..9c2bbf5
--- /dev/null
+++ b/src/com/google/inject/InternalToContextualFactoryAdapter.java
@@ -0,0 +1,25 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+*/
+class InternalToContextualFactoryAdapter<T>
+ implements InternalFactory<T> {
+
+ private final ContextualFactory<? extends T> factory;
+
+ public InternalToContextualFactoryAdapter(
+ ContextualFactory<? extends T> factory) {
+ this.factory = factory;
+ }
+
+ public T get(InternalContext context) {
+ return factory.get(context.getExternalContext());
+ }
+
+ public String toString() {
+ return factory.toString();
+ }
+}