Combined validation with constructor lookup and got rid of a volatile field check every time we create an object.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@119 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index ff35b18..06a7481 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -118,31 +118,11 @@
this.proxyFactoryBuilder = new ProxyFactoryBuilder();
}
- final List<Validation> validations = new ArrayList<Validation>();
+ final List<CreationListener> creationListeners
+ = new ArrayList<CreationListener>();
- /**
- * Registers a type to be validated for injection when we create the
- * container.
- */
- void requestValidation(final ErrorHandler errorHandler, final Class<?> type) {
- validations.add(new Validation() {
- public void run(final ContainerImpl container) {
- container.withErrorHandler(errorHandler,
- new Runnable() {
- public void run() {
- container.getConstructor(type);
- }
- });
- }
- });
- }
-
- /**
- * A validation command to run after we create the container but before
- * we return it to the client.
- */
- interface Validation {
- void run(ContainerImpl container);
+ interface CreationListener {
+ void notify(ContainerImpl container);
}
/**
@@ -327,9 +307,8 @@
stopwatch.resetAndLog(logger, "Binding indexing");
- // Run validations.
- for (Validation validation : validations) {
- validation.run(container);
+ for (CreationListener creationListener : creationListeners) {
+ creationListener.notify(container);
}
stopwatch.resetAndLog(logger, "Validation");
@@ -553,11 +532,19 @@
* the scope based on the @{@link Scoped} annotation on the implementation
* class if present.
*/
- public <I extends T> BindingBuilder<T> to(TypeLiteral<I> implementation) {
+ public <I extends T> BindingBuilder<T> to(
+ final TypeLiteral<I> implementation) {
ensureImplementationIsNotSet();
- requestValidation(errorHandler, implementation.getRawType());
this.implementation = implementation;
- this.factory = new DefaultFactory<I>(key, implementation);
+ final DefaultFactory<I> defaultFactory
+ = new DefaultFactory<I>(key, implementation);
+ this.factory = defaultFactory;
+ creationListeners.add(new CreationListener() {
+ public void notify(ContainerImpl container) {
+ defaultFactory.setConstructor(
+ container.getConstructor(implementation));
+ }
+ });
return this;
}
@@ -697,22 +684,22 @@
*/
private static class DefaultFactory<T> implements InternalFactory<T> {
- volatile ConstructorInjector<T> constructor;
-
private final TypeLiteral<T> implementation;
private final Key<? super T> key;
- public DefaultFactory(Key<? super T> key, TypeLiteral<T> implementation) {
+ ConstructorInjector<T> constructor;
+
+ DefaultFactory(Key<? super T> key, TypeLiteral<T> implementation) {
this.key = key;
this.implementation = implementation;
}
+ void setConstructor(ConstructorInjector<T> constructor) {
+ this.constructor = constructor;
+ }
+
@SuppressWarnings("unchecked")
public T get(InternalContext context) {
- if (constructor == null) {
- this.constructor
- = context.getContainerImpl().getConstructor(implementation);
- }
return (T) constructor.construct(context, key.getRawType());
}