Add support for explicit generic type in PayloadApplicationEvent
See gh-24599
This commit is contained in:
parent
7794606305
commit
6283456ef2
|
|
@ -20,6 +20,7 @@ import java.util.function.Consumer;
|
|||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.ResolvableTypeProvider;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
|
@ -27,6 +28,7 @@ import org.springframework.util.Assert;
|
|||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Juergen Hoeller
|
||||
* @author Qimiao Chen
|
||||
* @since 4.2
|
||||
* @param <T> the payload type of the event
|
||||
* @see ApplicationEventPublisher#publishEvent(Object)
|
||||
|
|
@ -37,6 +39,8 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
|
|||
|
||||
private final T payload;
|
||||
|
||||
@Nullable
|
||||
private ResolvableType payloadType;
|
||||
|
||||
/**
|
||||
* Create a new PayloadApplicationEvent.
|
||||
|
|
@ -44,15 +48,29 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
|
|||
* @param payload the payload object (never {@code null})
|
||||
*/
|
||||
public PayloadApplicationEvent(Object source, T payload) {
|
||||
this(source, payload, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PayloadApplicationEvent.
|
||||
* @param source the object on which the event initially occurred (never {@code null})
|
||||
* @param payload the payload object (never {@code null})
|
||||
* @param payloadType the type object of payload object (can be {@code null})
|
||||
*/
|
||||
public PayloadApplicationEvent(Object source, T payload, @Nullable ResolvableType payloadType) {
|
||||
super(source);
|
||||
Assert.notNull(payload, "Payload must not be null");
|
||||
this.payload = payload;
|
||||
this.payloadType = payloadType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResolvableType getResolvableType() {
|
||||
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getPayload()));
|
||||
if (this.payloadType == null) {
|
||||
this.payloadType = ResolvableType.forInstance(getPayload());
|
||||
}
|
||||
return ResolvableType.forClassWithGenerics(getClass(), this.payloadType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
applicationEvent = (ApplicationEvent) event;
|
||||
}
|
||||
else {
|
||||
applicationEvent = new PayloadApplicationEvent<>(this, event);
|
||||
applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
|
||||
if (eventType == null) {
|
||||
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ import org.springframework.context.event.test.GenericEventPojo;
|
|||
import org.springframework.context.event.test.Identifiable;
|
||||
import org.springframework.context.event.test.TestEvent;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
|
@ -622,6 +623,17 @@ class AnnotationDrivenEventListenerTests {
|
|||
this.eventCollector.assertNoEventReceived(listener);
|
||||
this.eventCollector.assertTotalEventsCount(0);
|
||||
}
|
||||
@Test
|
||||
public void publishEventWithGeneric() throws NoSuchMethodException {
|
||||
MyAnnotationConfigApplicationContext ctx = new MyAnnotationConfigApplicationContext();
|
||||
context = ctx;
|
||||
ctx.register(MyEventWithGenericListener.class);
|
||||
ctx.refresh();
|
||||
ResolvableType resolvableType = ResolvableType.forMethodParameter(MyEventWithGenericListener.class.getMethod("onMyEventWithGeneric",MyEventWithGeneric.class),0);
|
||||
ctx.publishEvent(new MyEventWithGeneric<String>(),resolvableType);
|
||||
assertThat(MyEventWithGenericListener.count).isEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void orderedListeners() {
|
||||
|
|
@ -1134,4 +1146,29 @@ class AnnotationDrivenEventListenerTests {
|
|||
}
|
||||
}
|
||||
|
||||
public static class MyAnnotationConfigApplicationContext extends AnnotationConfigApplicationContext{
|
||||
|
||||
@Override
|
||||
public void publishEvent(Object event, ResolvableType eventType) {
|
||||
super.publishEvent(event, eventType);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyEventWithGeneric<T> {
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class MyEventWithGenericListener{
|
||||
|
||||
public static int count ;
|
||||
|
||||
@EventListener
|
||||
public void onMyEventWithGeneric(MyEventWithGeneric<String> event){
|
||||
count ++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue