Add ResolvableTypeProvider

Provide a mean to detect the actual ResolvableType based on a instance as
a counter measure to type erasure.

Upgrade the event infrastructure to detect if the event (or the payload)
implements such interface. When this is the case, the return value of
`getResolvableType` is used to validate its generic type against the
method signature of the listener.

Issue: SPR-13069
This commit is contained in:
Stephane Nicoll
2015-06-03 15:30:47 +02:00
parent a7aaf313d7
commit b87816ed20
10 changed files with 217 additions and 7 deletions

View File

@@ -133,6 +133,34 @@ public class ResolvableTypeTests {
assertTrue(type.isAssignableFrom(String.class));
}
@Test
public void forInstanceMustNotBeNull() {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Instance must not be null");
ResolvableType.forInstance(null);
}
@Test
public void forInstanceNoProvider() {
ResolvableType type = ResolvableType.forInstance(new Object());
assertThat(type.getType(), equalTo(Object.class));
assertThat(type.resolve(), equalTo(Object.class));
}
@Test
public void forInstanceProvider() {
ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType<String>(String.class));
assertThat(type.getRawClass(), equalTo(MyGenericInterfaceType.class));
assertThat(type.getGeneric().resolve(), equalTo(String.class));
}
@Test
public void forInstanceProviderNull() {
ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType<String>(null));
assertThat(type.getType(), equalTo(MyGenericInterfaceType.class));
assertThat(type.resolve(), equalTo(MyGenericInterfaceType.class));
}
@Test
public void forField() throws Exception {
Field field = Fields.class.getField("charSequenceList");
@@ -1454,6 +1482,23 @@ public class ResolvableTypeTests {
public interface MyInterfaceType<T> {
}
public class MyGenericInterfaceType<T> implements MyInterfaceType<T>, ResolvableTypeProvider {
private final Class<T> type;
public MyGenericInterfaceType(Class<T> type) {
this.type = type;
}
@Override
public ResolvableType getResolvableType() {
if (this.type == null) {
return null;
}
return ResolvableType.forClassWithGenerics(getClass(), this.type);
}
}
public class MySimpleInterfaceType implements MyInterfaceType<String> {
}