GH-726 - Only create event publication registry entries for after commit listeners.
This commit is contained in:
@@ -187,7 +187,8 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
|||||||
.map(it -> executeListenerWithCompletion(publication, it)) //
|
.map(it -> executeListenerWithCompletion(publication, it)) //
|
||||||
.orElseGet(() -> {
|
.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;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -195,7 +196,7 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
|||||||
private void doResubmitUncompletedPublicationsOlderThan(@Nullable Duration duration,
|
private void doResubmitUncompletedPublicationsOlderThan(@Nullable Duration duration,
|
||||||
Predicate<EventPublication> filter) {
|
Predicate<EventPublication> filter) {
|
||||||
|
|
||||||
var message = duration != null ? " older than %s".formatted(duration): "";;
|
var message = duration != null ? " older than %s".formatted(duration) : "";
|
||||||
var registry = this.registry.get();
|
var registry = this.registry.get();
|
||||||
|
|
||||||
LOGGER.debug("Looking up incomplete event publications {}… ", message);
|
LOGGER.debug("Looking up incomplete event publications {}… ", message);
|
||||||
@@ -317,32 +318,11 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
|
|||||||
this.listeners = (List) listeners.stream()
|
this.listeners = (List) listeners.stream()
|
||||||
.filter(TransactionalApplicationListener.class::isInstance)
|
.filter(TransactionalApplicationListener.class::isInstance)
|
||||||
.map(TransactionalApplicationListener.class::cast)
|
.map(TransactionalApplicationListener.class::cast)
|
||||||
|
.filter(it -> it.getTransactionPhase().equals(TransactionPhase.AFTER_COMMIT))
|
||||||
.sorted(AnnotationAwareOrderComparator.INSTANCE)
|
.sorted(AnnotationAwareOrderComparator.INSTANCE)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransactionalEventListeners(
|
|
||||||
List<TransactionalApplicationListener<ApplicationEvent>> 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<TransactionalApplicationListener<ApplicationEvent>> collect = listeners.stream()
|
|
||||||
.filter(it -> it.getTransactionPhase().equals(phase))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return new TransactionalEventListeners(collect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the given {@link Consumer} for all transactional event listeners.
|
* Invokes the given {@link Consumer} for all transactional event listeners.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static org.mockito.Mockito.*;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
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.core.env.StandardEnvironment;
|
||||||
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
import org.springframework.modulith.events.core.EventPublicationRegistry;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.event.TransactionPhase;
|
||||||
|
import org.springframework.transaction.event.TransactionalApplicationListener;
|
||||||
import org.springframework.transaction.event.TransactionalEventListener;
|
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) {
|
private void assertListenerSelected(SampleEvent event, boolean expected) {
|
||||||
|
|
||||||
var listeners = multicaster.getApplicationListeners(new PayloadApplicationEvent<>(this, event),
|
var listeners = multicaster.getApplicationListeners(new PayloadApplicationEvent<>(this, event),
|
||||||
|
|||||||
Reference in New Issue
Block a user