Polishing
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -79,10 +79,11 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
||||
* to invoke each listener with.
|
||||
* <p>Default is equivalent to {@link org.springframework.core.task.SyncTaskExecutor},
|
||||
* executing all listeners synchronously in the calling thread.
|
||||
* <p>Consider specifying an asynchronous task executor here to not block the
|
||||
* caller until all listeners have been executed. However, note that asynchronous
|
||||
* execution will not participate in the caller's thread context (class loader,
|
||||
* transaction association) unless the TaskExecutor explicitly supports this.
|
||||
* <p>Consider specifying an asynchronous task executor here to not block the caller
|
||||
* until all listeners have been executed. However, note that asynchronous execution
|
||||
* will not participate in the caller's thread context (class loader, transaction context)
|
||||
* unless the TaskExecutor explicitly supports this.
|
||||
* @since 2.0
|
||||
* @see org.springframework.core.task.SyncTaskExecutor
|
||||
* @see org.springframework.core.task.SimpleAsyncTaskExecutor
|
||||
*/
|
||||
@@ -92,6 +93,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
|
||||
|
||||
/**
|
||||
* Return the current task executor for this multicaster.
|
||||
* @since 2.0
|
||||
*/
|
||||
@Nullable
|
||||
protected Executor getTaskExecutor() {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(FixedRateTaskConfig.class);
|
||||
assertThat(ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks()).hasSize(2);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThanOrEqualTo(10);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(FixedRateTaskConfigSubclass.class);
|
||||
assertThat(ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks()).hasSize(2);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThanOrEqualTo(10);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(ExplicitSchedulerConfig.class);
|
||||
assertThat(ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks()).hasSize(1);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThanOrEqualTo(10);
|
||||
assertThat(ctx.getBean(ExplicitSchedulerConfig.class).threadName).startsWith("explicitScheduler-");
|
||||
assertThat(Arrays.asList(ctx.getDefaultListableBeanFactory().getDependentBeans("myTaskScheduler")).contains(
|
||||
@@ -102,7 +102,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(ExplicitScheduledTaskRegistrarConfig.class);
|
||||
assertThat(ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks()).hasSize(1);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThanOrEqualTo(10);
|
||||
assertThat(ctx.getBean(ExplicitScheduledTaskRegistrarConfig.class).threadName).startsWith("explicitScheduler1");
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(
|
||||
SchedulingEnabled_withAmbiguousTaskSchedulers_andSingleTask_disambiguatedByScheduledTaskRegistrar.class);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(ThreadAwareWorker.class).executedByThread).startsWith("explicitScheduler2-");
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class EnableSchedulingTests {
|
||||
ctx = new AnnotationConfigApplicationContext(
|
||||
SchedulingEnabled_withAmbiguousTaskSchedulers_andSingleTask_disambiguatedBySchedulerNameAttribute.class);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(ThreadAwareWorker.class).executedByThread).startsWith("explicitScheduler2-");
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class EnableSchedulingTests {
|
||||
public void withTaskAddedVia_configureTasks() throws InterruptedException {
|
||||
ctx = new AnnotationConfigApplicationContext(SchedulingEnabled_withTaskAddedVia_configureTasks.class);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(ThreadAwareWorker.class).executedByThread).startsWith("taskScheduler-");
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public class EnableSchedulingTests {
|
||||
public void withTriggerTask() throws InterruptedException {
|
||||
ctx = new AnnotationConfigApplicationContext(TriggerTaskConfig.class);
|
||||
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(110);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThan(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -85,7 +85,7 @@ public abstract class ConnectionFactoryUtils {
|
||||
*/
|
||||
public static Mono<Connection> getConnection(ConnectionFactory connectionFactory) {
|
||||
return doGetConnection(connectionFactory)
|
||||
.onErrorMap(e -> new DataAccessResourceFailureException("Failed to obtain R2DBC Connection", e));
|
||||
.onErrorMap(ex -> new DataAccessResourceFailureException("Failed to obtain R2DBC Connection", ex));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,17 +124,17 @@ public abstract class ConnectionFactoryUtils {
|
||||
holderToUse.setConnection(conn);
|
||||
}
|
||||
holderToUse.requested();
|
||||
synchronizationManager
|
||||
.registerSynchronization(new ConnectionSynchronization(holderToUse, connectionFactory));
|
||||
synchronizationManager.registerSynchronization(
|
||||
new ConnectionSynchronization(holderToUse, connectionFactory));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
if (holderToUse != conHolder) {
|
||||
synchronizationManager.bindResource(connectionFactory, holderToUse);
|
||||
}
|
||||
}) // Unexpected exception from external delegation call -> close Connection and rethrow.
|
||||
.onErrorResume(e -> releaseConnection(connection, connectionFactory).then(Mono.error(e))));
|
||||
.onErrorResume(ex -> releaseConnection(connection, connectionFactory).then(Mono.error(ex))));
|
||||
}
|
||||
return con;
|
||||
}).onErrorResume(NoTransactionException.class, e -> Mono.from(connectionFactory.create()));
|
||||
}).onErrorResume(NoTransactionException.class, ex -> Mono.from(connectionFactory.create()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,7 +159,7 @@ public abstract class ConnectionFactoryUtils {
|
||||
*/
|
||||
public static Mono<Void> releaseConnection(Connection con, ConnectionFactory connectionFactory) {
|
||||
return doReleaseConnection(con, connectionFactory)
|
||||
.onErrorMap(e -> new DataAccessResourceFailureException("Failed to close R2DBC Connection", e));
|
||||
.onErrorMap(ex -> new DataAccessResourceFailureException("Failed to close R2DBC Connection", ex));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,15 +171,14 @@ public abstract class ConnectionFactoryUtils {
|
||||
* @see #doGetConnection
|
||||
*/
|
||||
public static Mono<Void> doReleaseConnection(Connection connection, ConnectionFactory connectionFactory) {
|
||||
return TransactionSynchronizationManager.forCurrentTransaction()
|
||||
.flatMap(synchronizationManager -> {
|
||||
return TransactionSynchronizationManager.forCurrentTransaction().flatMap(synchronizationManager -> {
|
||||
ConnectionHolder conHolder = (ConnectionHolder) synchronizationManager.getResource(connectionFactory);
|
||||
if (conHolder != null && connectionEquals(conHolder, connection)) {
|
||||
// It's the transactional Connection: Don't close it.
|
||||
conHolder.released();
|
||||
}
|
||||
return Mono.from(connection.close());
|
||||
}).onErrorResume(NoTransactionException.class, e -> Mono.from(connection.close()));
|
||||
}).onErrorResume(NoTransactionException.class, ex -> Mono.from(connection.close()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +267,8 @@ public abstract class ConnectionFactoryUtils {
|
||||
Connection heldCon = conHolder.getConnection();
|
||||
// Explicitly check for identity too: for Connection handles that do not implement
|
||||
// "equals" properly).
|
||||
return (heldCon == passedInCon || heldCon.equals(passedInCon) || getTargetConnection(heldCon).equals(passedInCon));
|
||||
return (heldCon == passedInCon || heldCon.equals(passedInCon) ||
|
||||
getTargetConnection(heldCon).equals(passedInCon));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -46,10 +46,10 @@ public abstract class TransactionContextManager {
|
||||
* transactional context holder. Context retrieval fails with NoTransactionException
|
||||
* if no context or context holder is registered.
|
||||
* @return the current {@link TransactionContext}
|
||||
* @throws NoTransactionException if no TransactionContext was found in the subscriber context
|
||||
* or no context found in a holder
|
||||
* @throws NoTransactionException if no TransactionContext was found in the
|
||||
* subscriber context or no context found in a holder
|
||||
*/
|
||||
public static Mono<TransactionContext> currentContext() throws NoTransactionException {
|
||||
public static Mono<TransactionContext> currentContext() {
|
||||
return Mono.deferContextual(ctx -> {
|
||||
if (ctx.hasKey(TransactionContext.class)) {
|
||||
return Mono.just(ctx.get(TransactionContext.class));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -32,8 +32,8 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Central delegate that manages resources and transaction synchronizations per
|
||||
* subscriber context.
|
||||
* To be used by resource management code but not by typical application code.
|
||||
* subscriber context. To be used by resource management code but not by typical
|
||||
* application code.
|
||||
*
|
||||
* <p>Supports one resource per key without overwriting, that is, a resource needs
|
||||
* to be removed before a new one can be set for the same key.
|
||||
@@ -73,6 +73,7 @@ public class TransactionSynchronizationManager {
|
||||
|
||||
|
||||
public TransactionSynchronizationManager(TransactionContext transactionContext) {
|
||||
Assert.notNull(transactionContext, "TransactionContext must not be null");
|
||||
this.transactionContext = transactionContext;
|
||||
}
|
||||
|
||||
@@ -88,10 +89,11 @@ public class TransactionSynchronizationManager {
|
||||
return TransactionContextManager.currentContext().map(TransactionSynchronizationManager::new);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if there is a resource for the given key bound to the current thread.
|
||||
* Check if there is a resource for the given key bound to the current context.
|
||||
* @param key the key to check (usually the resource factory)
|
||||
* @return if there is a value bound to the current thread
|
||||
* @return if there is a value bound to the current context
|
||||
*/
|
||||
public boolean hasResource(Object key) {
|
||||
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
|
||||
@@ -100,9 +102,9 @@ public class TransactionSynchronizationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a resource for the given key that is bound to the current thread.
|
||||
* Retrieve a resource for the given key that is bound to the current context.
|
||||
* @param key the key to check (usually the resource factory)
|
||||
* @return a value bound to the current thread (usually the active
|
||||
* @return a value bound to the current context (usually the active
|
||||
* resource object), or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -57,6 +57,7 @@ import static org.springframework.transaction.event.TransactionPhase.BEFORE_COMM
|
||||
|
||||
/**
|
||||
* Integration tests for {@link TransactionalEventListener} support
|
||||
* with thread-bound transactions.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
@@ -87,7 +88,6 @@ public class TransactionalEventListenerTests {
|
||||
getEventCollector().assertEvents(EventCollector.IMMEDIATELY, "test");
|
||||
getEventCollector().assertTotalEventsCount(1);
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertEvents(EventCollector.IMMEDIATELY, "test");
|
||||
getEventCollector().assertTotalEventsCount(1);
|
||||
@@ -115,7 +115,6 @@ public class TransactionalEventListenerTests {
|
||||
getContext().publishEvent("test");
|
||||
getEventCollector().assertNoEventReceived();
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertEvents(EventCollector.AFTER_COMPLETION, "test");
|
||||
getEventCollector().assertTotalEventsCount(1); // After rollback not invoked
|
||||
@@ -129,7 +128,6 @@ public class TransactionalEventListenerTests {
|
||||
getEventCollector().assertNoEventReceived();
|
||||
status.setRollbackOnly();
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertEvents(EventCollector.AFTER_COMPLETION, "test");
|
||||
getEventCollector().assertTotalEventsCount(1); // After rollback not invoked
|
||||
@@ -142,7 +140,6 @@ public class TransactionalEventListenerTests {
|
||||
getContext().publishEvent("test");
|
||||
getEventCollector().assertNoEventReceived();
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertEvents(EventCollector.AFTER_COMMIT, "test");
|
||||
getEventCollector().assertTotalEventsCount(1); // After rollback not invoked
|
||||
@@ -307,13 +304,12 @@ public class TransactionalEventListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void afterCommitMetaAnnotation() throws Exception {
|
||||
public void afterCommitMetaAnnotation() {
|
||||
load(AfterCommitMetaAnnotationTestListener.class);
|
||||
this.transactionTemplate.execute(status -> {
|
||||
getContext().publishEvent("test");
|
||||
getEventCollector().assertNoEventReceived();
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertEvents(EventCollector.AFTER_COMMIT, "test");
|
||||
getEventCollector().assertTotalEventsCount(1);
|
||||
@@ -326,7 +322,6 @@ public class TransactionalEventListenerTests {
|
||||
getContext().publishEvent("SKIP");
|
||||
getEventCollector().assertNoEventReceived();
|
||||
return null;
|
||||
|
||||
});
|
||||
getEventCollector().assertNoEventReceived();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -61,7 +61,7 @@ import org.springframework.web.util.pattern.PatternParseException;
|
||||
*/
|
||||
public final class MappedInterceptor implements HandlerInterceptor {
|
||||
|
||||
private static PathMatcher defaultPathMatcher = new AntPathMatcher();
|
||||
private static final PathMatcher defaultPathMatcher = new AntPathMatcher();
|
||||
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user