From 61bcafeaed30ca2a9b5eb3c58d1b7058e94dbb09 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Sun, 14 Jul 2024 19:10:55 +0200 Subject: [PATCH] GH-732 - Only create event publication registry entries for after commit listeners. --- ...PersistentApplicationEventMulticaster.java | 28 +++---------------- ...tApplicationEventMulticasterUnitTests.java | 17 +++++++++++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticaster.java b/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticaster.java index 5b1c5eaf..5172c5db 100644 --- a/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticaster.java +++ b/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticaster.java @@ -187,7 +187,8 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv .map(it -> executeListenerWithCompletion(publication, it)) // .orElseGet(() -> { - LOGGER.error("Listener {} not found! Skipping invocation and leaving event publication {} incomplete.", publication.getTargetIdentifier(), publication.getIdentifier()); + LOGGER.error("Listener {} not found! Skipping invocation and leaving event publication {} incomplete.", + publication.getTargetIdentifier(), publication.getIdentifier()); return null; }); } @@ -195,7 +196,7 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv private void doResubmitUncompletedPublicationsOlderThan(@Nullable Duration duration, Predicate filter) { - var message = duration != null ? " older than %s".formatted(duration): "";; + var message = duration != null ? " older than %s".formatted(duration) : ""; var registry = this.registry.get(); LOGGER.debug("Looking up incomplete event publications {}… ", message); @@ -317,32 +318,11 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv this.listeners = (List) listeners.stream() .filter(TransactionalApplicationListener.class::isInstance) .map(TransactionalApplicationListener.class::cast) + .filter(it -> it.getTransactionPhase().equals(TransactionPhase.AFTER_COMMIT)) .sorted(AnnotationAwareOrderComparator.INSTANCE) .toList(); } - private TransactionalEventListeners( - List> listeners) { - this.listeners = listeners; - } - - /** - * Returns all {@link TransactionalEventListeners} for the given {@link TransactionPhase}. - * - * @param phase must not be {@literal null}. - * @return will never be {@literal null}. - */ - public TransactionalEventListeners forPhase(TransactionPhase phase) { - - Assert.notNull(phase, "TransactionPhase must not be null!"); - - List> collect = listeners.stream() - .filter(it -> it.getTransactionPhase().equals(phase)) - .toList(); - - return new TransactionalEventListeners(collect); - } - /** * Invokes the given {@link Consumer} for all transactional event listeners. * diff --git a/spring-modulith-events/spring-modulith-events-core/src/test/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticasterUnitTests.java b/spring-modulith-events/spring-modulith-events-core/src/test/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticasterUnitTests.java index e003b1a9..2959954b 100644 --- a/spring-modulith-events/spring-modulith-events-core/src/test/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticasterUnitTests.java +++ b/spring-modulith-events/spring-modulith-events-core/src/test/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticasterUnitTests.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import lombok.AllArgsConstructor; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.BeforeEach; @@ -33,6 +34,8 @@ import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.modulith.events.core.EventPublicationRegistry; import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalApplicationListener; import org.springframework.transaction.event.TransactionalEventListener; /** @@ -87,6 +90,20 @@ class PersistentApplicationEventMulticasterUnitTests { } } + @Test // GH-726 + void onlyConsidersAfterCommitListeners() { + + var afterCommitListener = TransactionalApplicationListener.forPayload(TransactionPhase.AFTER_COMMIT, __ -> {}); + var beforeCommitListener = TransactionalApplicationListener.forPayload(TransactionPhase.BEFORE_COMMIT, __ -> {}); + + var eventListeners = new PersistentApplicationEventMulticaster.TransactionalEventListeners( + List.of(afterCommitListener, beforeCommitListener)); + + assertThat(eventListeners.stream()) + .hasSize(1) + .element(0).isEqualTo(afterCommitListener); + } + private void assertListenerSelected(SampleEvent event, boolean expected) { var listeners = multicaster.getApplicationListeners(new PayloadApplicationEvent<>(this, event),