Merge branch '6.0.x'

This commit is contained in:
Juergen Hoeller
2023-05-10 17:19:39 +02:00
6 changed files with 258 additions and 69 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,19 +41,6 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
private final ResolvableType payloadType;
/**
* 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})
* @since 6.0
*/
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 != null) ? payloadType : ResolvableType.forInstance(payload);
}
/**
* Create a new PayloadApplicationEvent, using the instance to infer its type.
@@ -64,6 +51,22 @@ public class PayloadApplicationEvent<T> extends ApplicationEvent implements Reso
this(source, payload, null);
}
/**
* Create a new PayloadApplicationEvent based on the provided payload type.
* @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}).
* Note that this is meant to indicate the payload type (e.g. {@code String}),
* not the full event type (such as {@code PayloadApplicationEvent<&lt;String&gt;}).
* @since 6.0
*/
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 != null ? payloadType : ResolvableType.forInstance(payload));
}
@Override
public ResolvableType getResolvableType() {

View File

@@ -128,12 +128,12 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
multicastEvent(event, null);
}
@Override
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
ResolvableType type = (eventType != null ? eventType : ResolvableType.forInstance(event));
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
@@ -145,10 +145,6 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
}
}
private ResolvableType resolveDefaultEventType(ApplicationEvent event) {
return ResolvableType.forInstance(event);
}
/**
* Invoke the given listener with the given event.
* @param listener the ApplicationListener to invoke

View File

@@ -385,23 +385,47 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Publish the given event to all listeners.
* <p>This is the internal delegate that all other {@code publishEvent}
* methods refer to. It is not meant to be called directly but rather serves
* as a propagation mechanism between application contexts in a hierarchy,
* potentially overridden in subclasses for a custom propagation arrangement.
* @param event the event to publish (may be an {@link ApplicationEvent}
* or a payload object to be turned into a {@link PayloadApplicationEvent})
* @param eventType the resolved event type, if known
* @param typeHint the resolved event type, if known.
* The implementation of this method also tolerates a payload type hint for
* a payload object to be turned into a {@link PayloadApplicationEvent}.
* However, the recommended way is to construct an actual event object via
* {@link PayloadApplicationEvent#PayloadApplicationEvent(Object, Object, ResolvableType)}
* instead for such scenarios.
* @since 4.2
* @see ApplicationEventMulticaster#multicastEvent(ApplicationEvent, ResolvableType)
*/
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
protected void publishEvent(Object event, @Nullable ResolvableType typeHint) {
Assert.notNull(event, "Event must not be null");
ResolvableType eventType = null;
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent applEvent) {
applicationEvent = applEvent;
eventType = typeHint;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event, eventType);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
ResolvableType payloadType = null;
if (typeHint != null && ApplicationEvent.class.isAssignableFrom(typeHint.toClass())) {
eventType = typeHint;
}
else {
payloadType = typeHint;
}
applicationEvent = new PayloadApplicationEvent<>(this, event, payloadType);
}
// Determine event type only once (for multicast and parent publish)
if (eventType == null) {
eventType = ResolvableType.forInstance(applicationEvent);
if (typeHint == null) {
typeHint = eventType;
}
}
@@ -416,7 +440,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext abstractApplicationContext) {
abstractApplicationContext.publishEvent(event, eventType);
abstractApplicationContext.publishEvent(event, typeHint);
}
else {
this.parent.publishEvent(event);