DATAREST-983 - AnnotatedEventHandlerInvoker now resolves generic handler method argument.

We now resolve the handler method argument type of an annotated repository event handler against the concrete handler type to make sure generics are resolved properly.
This commit is contained in:
Oliver Gierke
2017-01-24 16:46:33 +01:00
parent ca9d7f7b1d
commit 74cc5551a5
2 changed files with 44 additions and 4 deletions

View File

@@ -31,6 +31,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.rest.core.annotation.HandleAfterCreate;
@@ -165,13 +166,12 @@ public class AnnotatedEventHandlerInvoker implements ApplicationListener<Reposit
return;
}
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 0) {
if (method.getParameterCount() == 0) {
throw new IllegalStateException(String.format(PARAMETER_MISSING, method));
}
EventHandlerMethod handlerMethod = EventHandlerMethod.of(parameterTypes[0], handler, method);
ResolvableType parameter = ResolvableType.forMethodParameter(method, 0, handler.getClass());
EventHandlerMethod handlerMethod = EventHandlerMethod.of(parameter.resolve(), handler, method);
if (LOG.isDebugEnabled()) {
LOG.debug("Annotated handler method found: {}", handlerMethod);

View File

@@ -85,6 +85,23 @@ public class AnnotatedEventHandlerInvokerUnitTests {
assertThat(orderHandler1.timestamp, is(greaterThan(orderHandler2.timestamp)));
}
@Test // DATAREST-983
public void invokesEventHandlerOnParentClass() {
FirstEventHandler firstHandler = new FirstEventHandler();
SecondEventHandler secondHandler = new SecondEventHandler();
AnnotatedEventHandlerInvoker invoker = new AnnotatedEventHandlerInvoker();
invoker.postProcessAfterInitialization(firstHandler, "firstHandler");
invoker.postProcessAfterInitialization(secondHandler, "secondHandler");
invoker.onApplicationEvent(new BeforeCreateEvent(new FirstEntity()));
invoker.onApplicationEvent(new BeforeCreateEvent(new SecondEntity()));
assertThat(firstHandler.callCount, is(1));
assertThat(secondHandler.callCount, is(1));
}
@RepositoryEventHandler
static class Sample {
@@ -130,4 +147,27 @@ public class AnnotatedEventHandlerInvokerUnitTests {
timestamp = System.nanoTime();
}
}
// DATAREST-983
static class AbstractBaseEntityEventHandler<T extends BaseEntity> {
int callCount = 0;
@HandleBeforeCreate
private void method(T entity) {
callCount += 1;
}
}
@RepositoryEventHandler
static class FirstEventHandler extends AbstractBaseEntityEventHandler<FirstEntity> {}
@RepositoryEventHandler
static class SecondEventHandler extends AbstractBaseEntityEventHandler<SecondEntity> {}
static abstract class BaseEntity {}
static class FirstEntity extends BaseEntity {}
static class SecondEntity extends BaseEntity {}
}