Revision: 1229
Author: [email protected]
Date: Mon Sep 13 00:25:39 2010
Log: Remove support for com.google.inject annotations from miniguice.
Relying on JSR-330 classes only is simpler, and aligned with the goals for
the project.
Also fixing bugs where supertype fields weren't injected.
Also improving error reporting when an injection fails to include the
requiring injection. Otherwise things like "Expected injection of String"
fails miserably.
http://code.google.com/p/google-guice/source/detail?r=1229
Modified:
/trunk/extensions/mini/src/com/google/inject/mini/MiniGuice.java
/trunk/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
=======================================
--- /trunk/extensions/mini/src/com/google/inject/mini/MiniGuice.java Sat
Sep 11 01:46:08 2010
+++ /trunk/extensions/mini/src/com/google/inject/mini/MiniGuice.java Mon
Sep 13 00:25:39 2010
@@ -15,7 +15,6 @@
*/
package com.google.inject.mini;
-import com.google.inject.Provider;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -33,6 +32,7 @@
import java.util.Map;
import java.util.Queue;
import java.util.Set;
+import javax.inject.Provider;
/**
* Proof of concept. A tiny injector suitable for tiny applications.
@@ -45,7 +45,7 @@
private MiniGuice() {}
private final Map<Key, Provider<?>> bindings = new HashMap<Key,
Provider<?>>();
- private final Queue<Key> requiredKeys = new ArrayDeque<Key>();
+ private final Queue<RequiredKey> requiredKeys = new
ArrayDeque<RequiredKey>();
private final Set<Key> singletons = new HashSet<Key>();
/**
@@ -80,7 +80,7 @@
for (Object module : modules) {
miniGuice.install(module);
}
- miniGuice.requireKey(key);
+ miniGuice.requireKey(key, "root injection");
miniGuice.addJitBindings();
miniGuice.addProviderBindings();
miniGuice.eagerlyLoadSingletons();
@@ -98,15 +98,13 @@
return value;
}
};
- providerBindings.put(new Key(new
ProviderType(com.google.inject.Provider.class, key.type),
- key.annotation), providerProvider);
providerBindings.put(new Key(new
ProviderType(javax.inject.Provider.class, key.type),
key.annotation), providerProvider);
}
bindings.putAll(providerBindings);
}
- private void requireKey(Key key) {
+ private void requireKey(Key key, Object requiredBy) {
if (key.type instanceof ParameterizedType
&& (((ParameterizedType) key.type).getRawType() == Provider.class
|| ((ParameterizedType) key.type).getRawType() ==
javax.inject.Provider.class)) {
@@ -114,7 +112,7 @@
key = new Key(type, key.annotation);
}
- requiredKeys.add(key);
+ requiredKeys.add(new RequiredKey(key, requiredBy));
}
private void eagerlyLoadSingletons() {
@@ -148,6 +146,7 @@
private void addProviderMethodBinding(Key key, final Object instance,
final Method method) {
final Key[] parameterKeys = parametersToKeys(
method, method.getGenericParameterTypes(),
method.getParameterAnnotations());
+ method.setAccessible(true);
final Provider<Object> unscoped = new Provider<Object>() {
public Object get() {
Object[] parameters = keysToValues(parameterKeys);
@@ -161,25 +160,25 @@
}
};
- boolean singleton =
method.getAnnotation(com.google.inject.Singleton.class) != null
- || method.getAnnotation(javax.inject.Singleton.class) != null;
+ boolean singleton =
method.getAnnotation(javax.inject.Singleton.class) != null;
putBinding(key, unscoped, singleton);
}
private void addJitBindings() {
- Key requiredKey;
+ RequiredKey requiredKey;
while ((requiredKey = requiredKeys.poll()) != null) {
- if (bindings.containsKey(requiredKey)) {
+ Key key = requiredKey.key;
+ if (bindings.containsKey(key)) {
continue;
}
- if (!(requiredKey.type instanceof Class)) {
- throw new IllegalArgumentException("No binding for " +
requiredKey);
- }
- addJitBinding(requiredKey);
+ if (!(key.type instanceof Class) || key.annotation != null) {
+ throw new IllegalArgumentException("No binding for " + key);
+ }
+ addJitBinding(key, requiredKey.requiredBy);
}
}
- private void addJitBinding(Key key) {
+ private void addJitBinding(Key key, Object requiredBy) {
Class<?> type = (Class<?>) key.type;
/*
@@ -188,15 +187,15 @@
final List<Field> injectedFields = new ArrayList<Field>();
List<Object> fieldKeysList = new ArrayList<Object>();
for (Class<?> c = type; c != Object.class; c = c.getSuperclass()) {
- for (Field field : type.getDeclaredFields()) {
- if (field.getAnnotation(com.google.inject.Inject.class) == null
- && field.getAnnotation(javax.inject.Inject.class) == null) {
+ for (Field field : c.getDeclaredFields()) {
+ if (field.getAnnotation(javax.inject.Inject.class) == null) {
continue;
}
+ field.setAccessible(true);
injectedFields.add(field);
Key fieldKey = key(field, field.getGenericType(),
field.getAnnotations());
fieldKeysList.add(fieldKey);
- requireKey(fieldKey);
+ requireKey(fieldKey, field);
}
}
final Key[] fieldKeys = fieldKeysList.toArray(new
Key[fieldKeysList.size()]);
@@ -207,23 +206,25 @@
*/
Constructor<?> injectedConstructor = null;
for (Constructor<?> constructor : type.getDeclaredConstructors()) {
- if (constructor.getAnnotation(com.google.inject.Inject.class) == null
- && constructor.getAnnotation(javax.inject.Inject.class) == null)
{
+ if (constructor.getAnnotation(javax.inject.Inject.class) == null) {
continue;
}
if (injectedConstructor != null) {
throw new IllegalArgumentException("Too many injectable
constructors on " + type);
}
+ constructor.setAccessible(true);
injectedConstructor = constructor;
}
if (injectedConstructor == null) {
if (fieldKeys.length == 0) {
- throw new IllegalArgumentException("No injectable constructor on "
+ type);
+ throw new IllegalArgumentException("No injectable constructor on "
+ + type + " required by " + requiredBy);
}
try {
injectedConstructor = type.getConstructor();
} catch (NoSuchMethodException e) {
- throw new IllegalArgumentException("No injectable constructor on "
+ type);
+ throw new IllegalArgumentException("No injectable constructor on "
+ + type + " required by " + requiredBy);
}
}
@@ -253,8 +254,7 @@
}
};
- boolean singleton =
type.getAnnotation(com.google.inject.Singleton.class) != null
- || type.getAnnotation(javax.inject.Singleton.class) != null;
+ boolean singleton =
type.getAnnotation(javax.inject.Singleton.class) != null;
putBinding(new Key(type, null), unscoped, singleton);
}
@@ -288,8 +288,9 @@
private Key[] parametersToKeys(Member member, Type[] types,
Annotation[][] annotations) {
final Key[] parameterKeys = new Key[types.length];
for (int i = 0; i < parameterKeys.length; i++) {
- parameterKeys[i] = key(member + " parameter " + i, types[i],
annotations[i]);
- requireKey(parameterKeys[i]);
+ String name = member + " parameter " + i;
+ parameterKeys[i] = key(name, types[i], annotations[i]);
+ requireKey(parameterKeys[i], name);
}
return parameterKeys;
}
@@ -297,8 +298,7 @@
public Key key(Object subject, Type type, Annotation[] annotations) {
Annotation bindingAnnotation = null;
for (Annotation a : annotations) {
- if (a.annotationType().getAnnotation(javax.inject.Qualifier.class)
== null
- &&
a.annotationType().getAnnotation(com.google.inject.BindingAnnotation.class)
== null) {
+ if (a.annotationType().getAnnotation(javax.inject.Qualifier.class)
== null) {
continue;
}
if (bindingAnnotation != null) {
@@ -340,6 +340,16 @@
return "key[type=" + type + ",annotation=" + annotation + "]";
}
}
+
+ private class RequiredKey {
+ private final Key key;
+ private final Object requiredBy;
+
+ private RequiredKey(Key key, Object requiredBy) {
+ this.key = key;
+ this.requiredBy = requiredBy;
+ }
+ }
private static final class ProviderType implements ParameterizedType {
private final Class<?> rawType;
=======================================
--- /trunk/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
Sat Sep 11 01:46:08 2010
+++ /trunk/extensions/mini/test/com/google/inject/mini/MiniGuiceTest.java
Mon Sep 13 00:25:39 2010
@@ -15,12 +15,12 @@
*/
package com.google.inject.mini;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
import com.google.inject.Provides;
-import com.google.inject.Singleton;
import java.util.concurrent.atomic.AtomicReference;
+import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
import junit.framework.TestCase;
public final class MiniGuiceTest extends TestCase {
@@ -191,4 +191,34 @@
@Inject F f2;
@Inject Provider<F> fProvider;
}
-}
+
+ public void testNoJitBindingsForAnnotations() {
+ try {
+ MiniGuice.inject(O.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public static class O {
+ @Inject @Named("a") A a;
+ }
+
+ public void testSubclasses() {
+ Q q = MiniGuice.inject(Q.class, new Object() {
+ @Provides F provideF() {
+ return new F();
+ }
+ });
+
+ assertNotNull(q.f);
+ }
+
+ public static class P {
+ @Inject F f;
+ }
+
+ public static class Q extends P {
+ @Inject Q() {}
+ }
+}
--
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en.