Suppress ClassCastException for payload type mismatch as well
Closes gh-26349
This commit is contained in:
parent
b0abdee012
commit
4ac27e4dab
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.context;
|
package org.springframework.context;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.core.ResolvableTypeProvider;
|
import org.springframework.core.ResolvableTypeProvider;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
@ -23,11 +25,12 @@ import org.springframework.util.Assert;
|
||||||
/**
|
/**
|
||||||
* An {@link ApplicationEvent} that carries an arbitrary payload.
|
* An {@link ApplicationEvent} that carries an arbitrary payload.
|
||||||
*
|
*
|
||||||
* <p>Mainly intended for internal use within the framework.
|
|
||||||
*
|
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
* @param <T> the payload type of the event
|
* @param <T> the payload type of the event
|
||||||
|
* @see ApplicationEventPublisher#publishEvent(Object)
|
||||||
|
* @see ApplicationListener#forPayload(Consumer)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
|
public class PayloadApplicationEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.PayloadApplicationEvent;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ErrorHandler;
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
@ -55,6 +56,9 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
||||||
@Nullable
|
@Nullable
|
||||||
private ErrorHandler errorHandler;
|
private ErrorHandler errorHandler;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile Log lazyLogger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SimpleApplicationEventMulticaster.
|
* Create a new SimpleApplicationEventMulticaster.
|
||||||
|
|
@ -173,12 +177,18 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
||||||
}
|
}
|
||||||
catch (ClassCastException ex) {
|
catch (ClassCastException ex) {
|
||||||
String msg = ex.getMessage();
|
String msg = ex.getMessage();
|
||||||
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
|
if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
|
||||||
|
(event instanceof PayloadApplicationEvent &&
|
||||||
|
matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
|
||||||
// Possibly a lambda-defined listener which we could not resolve the generic event type for
|
// Possibly a lambda-defined listener which we could not resolve the generic event type for
|
||||||
// -> let's suppress the exception and just log a debug message.
|
// -> let's suppress the exception.
|
||||||
Log logger = LogFactory.getLog(getClass());
|
Log loggerToUse = this.lazyLogger;
|
||||||
if (logger.isTraceEnabled()) {
|
if (loggerToUse == null) {
|
||||||
logger.trace("Non-matching event type for listener: " + listener, ex);
|
loggerToUse = LogFactory.getLog(getClass());
|
||||||
|
this.lazyLogger = loggerToUse;
|
||||||
|
}
|
||||||
|
if (loggerToUse.isTraceEnabled()) {
|
||||||
|
loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -49,9 +49,11 @@ public class PayloadApplicationEventTests {
|
||||||
public void testProgrammaticEventListener() {
|
public void testProgrammaticEventListener() {
|
||||||
List<Auditable> events = new ArrayList<>();
|
List<Auditable> events = new ArrayList<>();
|
||||||
ApplicationListener<AuditablePayloadEvent<String>> listener = events::add;
|
ApplicationListener<AuditablePayloadEvent<String>> listener = events::add;
|
||||||
|
ApplicationListener<AuditablePayloadEvent<Integer>> mismatch = (event -> event.getPayload().intValue());
|
||||||
|
|
||||||
ConfigurableApplicationContext ac = new GenericApplicationContext();
|
ConfigurableApplicationContext ac = new GenericApplicationContext();
|
||||||
ac.addApplicationListener(listener);
|
ac.addApplicationListener(listener);
|
||||||
|
ac.addApplicationListener(mismatch);
|
||||||
ac.refresh();
|
ac.refresh();
|
||||||
|
|
||||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||||
|
|
@ -63,9 +65,11 @@ public class PayloadApplicationEventTests {
|
||||||
public void testProgrammaticPayloadListener() {
|
public void testProgrammaticPayloadListener() {
|
||||||
List<String> events = new ArrayList<>();
|
List<String> events = new ArrayList<>();
|
||||||
ApplicationListener<PayloadApplicationEvent<String>> listener = ApplicationListener.forPayload(events::add);
|
ApplicationListener<PayloadApplicationEvent<String>> listener = ApplicationListener.forPayload(events::add);
|
||||||
|
ApplicationListener<PayloadApplicationEvent<Integer>> mismatch = ApplicationListener.forPayload(payload -> payload.intValue());
|
||||||
|
|
||||||
ConfigurableApplicationContext ac = new GenericApplicationContext();
|
ConfigurableApplicationContext ac = new GenericApplicationContext();
|
||||||
ac.addApplicationListener(listener);
|
ac.addApplicationListener(listener);
|
||||||
|
ac.addApplicationListener(mismatch);
|
||||||
ac.refresh();
|
ac.refresh();
|
||||||
|
|
||||||
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
AuditablePayloadEvent<String> event = new AuditablePayloadEvent<>(this, "xyz");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue