Introduce TransactionalApplicationListener interface (with callback support)

Includes forPayload methods and common adapter classes for programmatic usage.
Aligns default order values for event handling delegates to LOWEST_PRECEDENCE.

Closes gh-24163
This commit is contained in:
Juergen Hoeller
2020-10-22 15:19:32 +02:00
parent cfc3522641
commit 95110d8257
19 changed files with 905 additions and 184 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@@ -17,6 +17,7 @@
package org.springframework.context;
import java.util.EventListener;
import java.util.function.Consumer;
/**
* Interface to be implemented by application event listeners.
@@ -45,4 +46,17 @@ public interface ApplicationListener<E extends ApplicationEvent> extends EventLi
*/
void onApplicationEvent(E event);
/**
* Create a new {@code ApplicationListener} for the given payload consumer.
* @param consumer the event payload consumer
* @param <T> the type of the event payload
* @return a corresponding {@code ApplicationListener} instance
* @since 5.3
* @see PayloadApplicationEvent
*/
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return event -> consumer.accept(event.getPayload());
}
}

View File

@@ -37,6 +37,7 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.Ordered;
import org.springframework.core.ReactiveAdapter;
import org.springframework.core.ReactiveAdapterRegistry;
import org.springframework.core.ResolvableType;
@@ -95,6 +96,12 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
private EventExpressionEvaluator evaluator;
/**
* Construct a new ApplicationListenerMethodAdapter.
* @param beanName the name of the bean to invoke the listener method on
* @param targetClass the target class that the method is declared on
* @param method the listener method to invoke
*/
public ApplicationListenerMethodAdapter(String beanName, Class<?> targetClass, Method method) {
this.beanName = beanName;
this.method = BridgeMethodResolver.findBridgedMethod(method);
@@ -135,7 +142,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
private static int resolveOrder(Method method) {
Order ann = AnnotatedElementUtils.findMergedAnnotation(method, Order.class);
return (ann != null ? ann.value() : 0);
return (ann != null ? ann.value() : Ordered.LOWEST_PRECEDENCE);
}
@@ -332,6 +339,14 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
return this.applicationContext.getBean(this.beanName);
}
/**
* Return the target listener method.
* @since 5.3
*/
protected Method getTargetMethod() {
return this.targetMethod;
}
/**
* Return the condition to use.
* <p>Matches the {@code condition} attribute of the {@link EventListener}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@@ -29,6 +29,7 @@ import org.springframework.core.Ordered;
*
* @author Stephane Nicoll
* @since 4.2
* @see ApplicationListenerMethodAdapter
*/
public class DefaultEventListenerFactory implements EventListenerFactory, Ordered {