Description
Oliver Drotbohm opened SPR-13069 and commented
Spring 4.2 introduces better matching of generic types for ApplicationEvent
instances. The matching now requires a complete generic match for an event being delivered to an ApplicationListener
. Assume the following scenario:
class EventWithPayload<T> {
public EventWithPayload(T source) {
super(source);
}
}
The main purpose of a generic type introduced in an ApplicationEvent
is to allow ApplicationListeners
to be declared to match that particular type:
class PersonEventListener implements ApplicationListener<EventWithPayload<Person>> { … }
The delivery of instances of such an event now only works if a dedicated sub-type that fills the generic parameter is used (e.g. a new EventWithPayload<Person>(person) {
} is thrown). However, if the generic type is used as is, delivery fails as the event type is basically interpreted as EventWithPayload<?>
and thus (understandably) doesn't match the generics matching.
I suggest to introduce an annotation that can be used on EventWithPayload
to let Spring Framework inspect the event's payload type and include that in the matching algorithm. It basically expresses: "in this event type the generic type is used to bind the payload".
@PayloadGenerics(0) // index of the generic parameter in case multiple ones are use, default to 0
class EventWithPayload<T> { … }
Alternatively, an idea might be to analyze the return type of getSource()
and inspect the payload if that method has been overridden to return any of the generic parameters of the type.
class EventWithPayload<T> {
public EventWithPayload(T source) {
super(source);
}
@Override
public T getSource() {
return (T) super.getSource();
}
}
Affects: 4.2 RC1