/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.event;
import java.util.function.Consumer;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
An ApplicationListener
that is invoked according to a TransactionPhase
. This is a programmatic equivalent of the TransactionalEventListener
annotation. Adding Ordered
to your listener implementation allows you to prioritize that listener amongst other listeners running before or after transaction completion.
NOTE: Transactional event listeners only work with thread-bound transactions managed by PlatformTransactionManager
. A reactive transaction managed by ReactiveTransactionManager
uses the Reactor context instead of thread-local attributes, so from the perspective of an event listener, there is no compatible active transaction that it can participate in.
Author: Juergen Hoeller, Oliver Drotbohm Type parameters: - <E> – the specific
ApplicationEvent
subclass to listen to
See Also: Since: 5.3
/**
* An {@link ApplicationListener} that is invoked according to a {@link TransactionPhase}.
* This is a programmatic equivalent of the {@link TransactionalEventListener} annotation.
*
* <p>Adding {@link org.springframework.core.Ordered} to your listener implementation
* allows you to prioritize that listener amongst other listeners running before or after
* transaction completion.
*
* <p><b>NOTE: Transactional event listeners only work with thread-bound transactions
* managed by {@link org.springframework.transaction.PlatformTransactionManager}.</b>
* A reactive transaction managed by {@link org.springframework.transaction.ReactiveTransactionManager}
* uses the Reactor context instead of thread-local attributes, so from the perspective of
* an event listener, there is no compatible active transaction that it can participate in.
*
* @author Juergen Hoeller
* @author Oliver Drotbohm
* @since 5.3
* @param <E> the specific {@code ApplicationEvent} subclass to listen to
* @see TransactionalEventListener
* @see TransactionalApplicationListenerAdapter
* @see #forPayload
*/
public interface TransactionalApplicationListener<E extends ApplicationEvent>
extends ApplicationListener<E>, Ordered {
Return the execution order within transaction synchronizations.
Default is Ordered.LOWEST_PRECEDENCE
.
See Also:
/**
* Return the execution order within transaction synchronizations.
* <p>Default is {@link Ordered#LOWEST_PRECEDENCE}.
* @see org.springframework.transaction.support.TransactionSynchronization#getOrder()
*/
@Override
default int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
Return the TransactionPhase
in which the listener will be invoked. The default phase is TransactionPhase.AFTER_COMMIT
.
/**
* Return the {@link TransactionPhase} in which the listener will be invoked.
* <p>The default phase is {@link TransactionPhase#AFTER_COMMIT}.
*/
default TransactionPhase getTransactionPhase() {
return TransactionPhase.AFTER_COMMIT;
}
Return an identifier for the listener to be able to refer to it individually.
It might be necessary for specific completion callback implementations
to provide a specific id, whereas for other scenarios an empty String
(as the common default value) is acceptable as well.
See Also: - addCallback
/**
* Return an identifier for the listener to be able to refer to it individually.
* <p>It might be necessary for specific completion callback implementations
* to provide a specific id, whereas for other scenarios an empty String
* (as the common default value) is acceptable as well.
* @see #addCallback
*/
default String getListenerId() {
return "";
}
Add a callback to be invoked on processing within transaction synchronization, i.e. when processEvent
is being triggered during actual transactions. Params: - callback – the synchronization callback to apply
/**
* Add a callback to be invoked on processing within transaction synchronization,
* i.e. when {@link #processEvent} is being triggered during actual transactions.
* @param callback the synchronization callback to apply
*/
void addCallback(SynchronizationCallback callback);
Immediately process the given ApplicationEvent
. In contrast to onApplicationEvent(ApplicationEvent)
, a call to this method will directly process the given event without deferring it to the associated transaction phase
. Params: - event – the event to process through the target listener implementation
/**
* Immediately process the given {@link ApplicationEvent}. In contrast to
* {@link #onApplicationEvent(ApplicationEvent)}, a call to this method will
* directly process the given event without deferring it to the associated
* {@link #getTransactionPhase() transaction phase}.
* @param event the event to process through the target listener implementation
*/
void processEvent(E event);
Create a new TransactionalApplicationListener
for the given payload consumer, to be applied in the default phase TransactionPhase.AFTER_COMMIT
. Params: - consumer – the event payload consumer
Type parameters: - <T> – the type of the event payload
See Also: - getPayload.getPayload()
- TransactionalApplicationListenerAdapter
Returns: a corresponding TransactionalApplicationListener
instance
/**
* Create a new {@code TransactionalApplicationListener} for the given payload consumer,
* to be applied in the default phase {@link TransactionPhase#AFTER_COMMIT}.
* @param consumer the event payload consumer
* @param <T> the type of the event payload
* @return a corresponding {@code TransactionalApplicationListener} instance
* @see PayloadApplicationEvent#getPayload()
* @see TransactionalApplicationListenerAdapter
*/
static <T> TransactionalApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return forPayload(TransactionPhase.AFTER_COMMIT, consumer);
}
Create a new TransactionalApplicationListener
for the given payload consumer. Params: - phase – the transaction phase in which to invoke the listener
- consumer – the event payload consumer
Type parameters: - <T> – the type of the event payload
See Also: - getPayload.getPayload()
- TransactionalApplicationListenerAdapter
Returns: a corresponding TransactionalApplicationListener
instance
/**
* Create a new {@code TransactionalApplicationListener} for the given payload consumer.
* @param phase the transaction phase in which to invoke the listener
* @param consumer the event payload consumer
* @param <T> the type of the event payload
* @return a corresponding {@code TransactionalApplicationListener} instance
* @see PayloadApplicationEvent#getPayload()
* @see TransactionalApplicationListenerAdapter
*/
static <T> TransactionalApplicationListener<PayloadApplicationEvent<T>> forPayload(
TransactionPhase phase, Consumer<T> consumer) {
TransactionalApplicationListenerAdapter<PayloadApplicationEvent<T>> listener =
new TransactionalApplicationListenerAdapter<>(event -> consumer.accept(event.getPayload()));
listener.setTransactionPhase(phase);
return listener;
}
Callback to be invoked on synchronization-driven event processing, wrapping the target listener invocation (processEvent
). See Also: - addCallback
- processEvent
/**
* Callback to be invoked on synchronization-driven event processing,
* wrapping the target listener invocation ({@link #processEvent}).
*
* @see #addCallback
* @see #processEvent
*/
interface SynchronizationCallback {
Called before transactional event listener invocation.
Params: - event – the event that transaction synchronization is about to process
/**
* Called before transactional event listener invocation.
* @param event the event that transaction synchronization is about to process
*/
default void preProcessEvent(ApplicationEvent event) {
}
Called after a transactional event listener invocation.
Params: - event – the event that transaction synchronization finished processing
- ex – an exception that occurred during listener invocation, if any
/**
* Called after a transactional event listener invocation.
* @param event the event that transaction synchronization finished processing
* @param ex an exception that occurred during listener invocation, if any
*/
default void postProcessEvent(ApplicationEvent event, @Nullable Throwable ex) {
}
}
}