Skip to content

Commit

Permalink
Merge pull request google#281 from cgruber/turnoffreflectioninmodules
Browse files Browse the repository at this point in the history
Remove reflective fallback for modules (and provides methods)
  • Loading branch information
cgruber committed Jun 30, 2013
2 parents cb95092 + e3a26c8 commit 6682d76
Show file tree
Hide file tree
Showing 18 changed files with 214 additions and 127 deletions.
5 changes: 5 additions & 0 deletions core/src/main/java/dagger/ObjectGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ public static ObjectGraph create(Object... modules) {
return DaggerObjectGraph.makeGraph(null, new FailoverLoader(), modules);
}

// visible for testing
static ObjectGraph createWith(Loader loader, Object... modules) {
return DaggerObjectGraph.makeGraph(null, loader, modules);
}

static class DaggerObjectGraph extends ObjectGraph {
private final DaggerObjectGraph base;
private final Linker linker;
Expand Down
43 changes: 23 additions & 20 deletions core/src/main/java/dagger/internal/FailoverLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import dagger.internal.loaders.GeneratedAdapters;
import dagger.internal.loaders.ReflectiveAtInjectBinding;
import dagger.internal.loaders.ReflectiveModuleAdapter;
import dagger.internal.loaders.ReflectiveStaticInjection;

/**
Expand All @@ -33,37 +32,41 @@ public final class FailoverLoader implements Loader {
* Obtains a module adapter for {@code module} from the first responding resolver.
*/
@Override public <T> ModuleAdapter<T> getModuleAdapter(Class<? extends T> type, T instance) {
ModuleAdapter<T> result = GeneratedAdapters.initModuleAdapter(type);
if (result == null) {
result = ReflectiveModuleAdapter.create(type);
ModuleAdapter<T> result = null;
try {
result = GeneratedAdapters.initModuleAdapter(type);
} catch (ClassNotFoundException e) {
throw new TypeNotPresentException(type + GeneratedAdapters.MODULE_ADAPTER_SUFFIX, e);
}
result.module = (instance != null) ? instance : result.newModule();
return result;
}

@Override public Binding<?> getAtInjectBinding(String key, String className,
ClassLoader classLoader, boolean mustHaveInjections) {
try {
Binding<?> result = GeneratedAdapters.initInjectAdapter(className, classLoader);
if (result == null) {
// A null classloader is the system classloader.
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader();
Class<?> c = classLoader.loadClass(className);
if (!c.isInterface()) {
result = ReflectiveAtInjectBinding.create(c, mustHaveInjections);
try {
return GeneratedAdapters.initInjectAdapter(className, classLoader);
} catch (ClassNotFoundException ignored /* failover case */) {
try {
// A null classloader is the system classloader.
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader();
Class<?> type = classLoader.loadClass(className);
if (!type.isInterface()) {
return null; // Short-circuit since we can't build reflective bindings for interfaces.
}
return ReflectiveAtInjectBinding.create(type, mustHaveInjections);
} catch (ClassNotFoundException e) {
throw new TypeNotPresentException(
String.format("Could not find %s needed for binding %s", className, key), e);
}
}
return result;
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not find " + className + " needed for binding " + key, e);
}
}

@Override public StaticInjection getStaticInjection(Class<?> injectedClass) {
StaticInjection result = GeneratedAdapters.initStaticInjection(injectedClass);
if (result == null) {
result = ReflectiveStaticInjection.create(injectedClass);
try {
return GeneratedAdapters.initStaticInjection(injectedClass);
} catch (ClassNotFoundException ignored) {
return ReflectiveStaticInjection.create(injectedClass);
}
return result;
}
}
3 changes: 2 additions & 1 deletion core/src/main/java/dagger/internal/Loader.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ Binding<?> getAtInjectBinding(
String key, String className, ClassLoader classLoader, boolean mustHaveInjections);

/**
* Returns a module adapter for {@code module}.
* Returns a module adapter for {@code module} or throws a {@code TypeNotPresentException} if
* none can be found.
*/
<T> ModuleAdapter<T> getModuleAdapter(Class<? extends T> moduleClass, T module);

Expand Down
30 changes: 20 additions & 10 deletions core/src/main/java/dagger/internal/loaders/GeneratedAdapters.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import dagger.internal.StaticInjection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
Expand All @@ -36,32 +35,43 @@ public final class GeneratedAdapters {

private GeneratedAdapters() { }

public static <T> ModuleAdapter<T> initModuleAdapter(Class<? extends T> moduleClass) {
/**
* Attempts to load an adapter named from the provided type plus a constant suffix
* {@link #MODULE_ADAPTER_SUFFIX}, or throws a {@code ClassNotFoundException}.
*/
public static <T> ModuleAdapter<T> initModuleAdapter(Class<? extends T> moduleClass)
throws ClassNotFoundException {
return instantiate(moduleClass.getName() + MODULE_ADAPTER_SUFFIX, moduleClass.getClassLoader());
}

public static Binding<?> initInjectAdapter(String className, ClassLoader classLoader) {
/**
* Attempts to load an adapter named from the provided class name plus a constant suffix
* {@link #INJECT_ADAPTER_SUFFIX}, or throws a {@code ClassNotFoundException}.
*/
public static Binding<?> initInjectAdapter(String className, ClassLoader classLoader)
throws ClassNotFoundException {
return instantiate(className + INJECT_ADAPTER_SUFFIX, classLoader);
}

public static StaticInjection initStaticInjection(Class<?> injectedClass) {
/**
* Attempts to load an adapter named from the provided type plus a constant suffix
* {@link #STATIC_INJECTION_SUFFIX}, or throws a {@code ClassNotFoundException}.
*/
public static StaticInjection initStaticInjection(Class<?> injectedClass)
throws ClassNotFoundException {
return instantiate(injectedClass.getName() + STATIC_INJECTION_SUFFIX,
injectedClass.getClassLoader());
}

private static <T> T instantiate(String name, ClassLoader classLoader) {
private static <T> T instantiate(String name, ClassLoader classLoader)
throws ClassNotFoundException {
try {
// A null classloader is the system classloader.
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader();
Class<?> generatedClass = classLoader.loadClass(name);
Constructor<?> constructor = generatedClass.getDeclaredConstructor();
constructor.setAccessible(true);
return (T) constructor.newInstance();
} catch (ClassNotFoundException e) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, name + " could not be found.", e);
}
return null; // Not finding a class is not inherently an error, unlike finding a bad class.
} catch (NoSuchMethodException e) {
throw new RuntimeException("No default constructor found on " + name, e);
} catch (InstantiationException e) {
Expand Down
8 changes: 5 additions & 3 deletions core/src/test/java/dagger/ExtensionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package dagger;

import dagger.internal.TestingLoader;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Singleton;
Expand Down Expand Up @@ -55,11 +56,12 @@ static class D {
static class ExtensionModule { }

@Test public void basicExtension() {
assertNotNull(ObjectGraph.create(new RootModule()).plus(new ExtensionModule()));
assertNotNull(ObjectGraph.createWith(new TestingLoader(), new RootModule())
.plus(new ExtensionModule()));
}

@Test public void basicInjection() {
ObjectGraph root = ObjectGraph.create(new RootModule());
ObjectGraph root = ObjectGraph.createWith(new TestingLoader(), new RootModule());
assertThat(root.get(A.class)).isNotNull();
assertThat(root.get(A.class)).isSameAs(root.get(A.class)); // Present and Singleton.
assertThat(root.get(B.class)).isNotSameAs(root.get(B.class)); // Not singleton.
Expand All @@ -77,7 +79,7 @@ static class ExtensionModule { }
}

@Test public void scopedGraphs() {
ObjectGraph app = ObjectGraph.create(new RootModule());
ObjectGraph app = ObjectGraph.createWith(new TestingLoader(), new RootModule());
assertThat(app.get(A.class)).isNotNull();
assertThat(app.get(A.class)).isSameAs(app.get(A.class));
assertThat(app.get(B.class)).isNotSameAs(app.get(B.class));
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/dagger/ExtensionWithStateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package dagger;

import dagger.internal.TestingLoader;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -48,7 +49,7 @@ static class ExtensionModule { }

@Test public void basicInjectionWithExtension() {
A a = new A();
ObjectGraph root = ObjectGraph.create(new RootModule(a));
ObjectGraph root = ObjectGraph.createWith(new TestingLoader(), new RootModule(a));
assertThat(root.get(A.class)).isSameAs(a);

// Extension graph behaves as the root graph would for root-ish things.
Expand Down
7 changes: 4 additions & 3 deletions core/src/test/java/dagger/InjectStaticsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package dagger;

import dagger.internal.TestingLoader;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -47,7 +48,7 @@ class TestModule {
}
}

ObjectGraph graph = ObjectGraph.create(new TestModule());
ObjectGraph graph = ObjectGraph.createWith(new TestingLoader(),new TestModule());
assertThat(InjectsOneField.staticField).isNull();
graph.injectStatics();
assertThat(InjectsOneField.staticField).isEqualTo("static");
Expand All @@ -66,7 +67,7 @@ class TestModule {
}
}

ObjectGraph graph = ObjectGraph.create(new TestModule());
ObjectGraph graph = ObjectGraph.createWith(new TestingLoader(), new TestModule());
assertThat(InjectsStaticAndNonStatic.staticField).isNull();
graph.injectStatics();
assertThat(InjectsStaticAndNonStatic.staticField).isEqualTo("static");
Expand All @@ -85,7 +86,7 @@ class TestModule {
}
}

ObjectGraph graph = ObjectGraph.create(new TestModule());
ObjectGraph graph = ObjectGraph.createWith(new TestingLoader(), new TestModule());
assertThat(InjectsStaticAndNonStatic.staticField).isNull();
InjectsStaticAndNonStatic object = new InjectsStaticAndNonStatic();
graph.inject(object);
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/dagger/InjectionOfLazyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package dagger;

import dagger.internal.TestingLoader;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
import javax.inject.Provider;
Expand Down Expand Up @@ -127,6 +128,6 @@ class TestModule {
}

private <T> T injectWithModule(T ep, Object ... modules) {
return ObjectGraph.create(modules).inject(ep);
return ObjectGraph.createWith(new TestingLoader(), modules).inject(ep);
}
}
Loading

0 comments on commit 6682d76

Please sign in to comment.