Merge pull request #38968 from quaff

* pr/38968:
  Polish "Add configuration property "spring.task.execution.pool.shutdown.accept-tasks-after-context-close""
  Add configuration property "spring.task.execution.pool.shutdown.accept-tasks-after-context-close"

Closes gh-38968
This commit is contained in:
Moritz Halbritter 2024-01-10 10:39:05 +01:00
commit 5c465115ac
5 changed files with 93 additions and 37 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Filip Hrisafov * @author Filip Hrisafov
* @author Yanming Zhou
* @since 2.1.0 * @since 2.1.0
*/ */
@ConfigurationProperties("spring.task.execution") @ConfigurationProperties("spring.task.execution")
@ -110,6 +111,8 @@ public class TaskExecutionProperties {
*/ */
private Duration keepAlive = Duration.ofSeconds(60); private Duration keepAlive = Duration.ofSeconds(60);
private final Shutdown shutdown = new Shutdown();
public int getQueueCapacity() { public int getQueueCapacity() {
return this.queueCapacity; return this.queueCapacity;
} }
@ -150,6 +153,28 @@ public class TaskExecutionProperties {
this.keepAlive = keepAlive; this.keepAlive = keepAlive;
} }
public Shutdown getShutdown() {
return this.shutdown;
}
public static class Shutdown {
/**
* Whether to accept further tasks after the application context close phase
* has begun.
*/
private boolean acceptTasksAfterContextClose;
public boolean isAcceptTasksAfterContextClose() {
return this.acceptTasksAfterContextClose;
}
public void setAcceptTasksAfterContextClose(boolean acceptTasksAfterContextClose) {
this.acceptTasksAfterContextClose = acceptTasksAfterContextClose;
}
}
} }
public static class Shutdown { public static class Shutdown {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,6 +43,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Yanming Zhou
*/ */
class TaskExecutorConfigurations { class TaskExecutorConfigurations {
@ -119,6 +120,7 @@ class TaskExecutorConfigurations {
builder = builder.maxPoolSize(pool.getMaxSize()); builder = builder.maxPoolSize(pool.getMaxSize());
builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout()); builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout());
builder = builder.keepAlive(pool.getKeepAlive()); builder = builder.keepAlive(pool.getKeepAlive());
builder = builder.acceptTasksAfterContextClose(pool.getShutdown().isAcceptTasksAfterContextClose());
TaskExecutionProperties.Shutdown shutdown = properties.getShutdown(); TaskExecutionProperties.Shutdown shutdown = properties.getShutdown();
builder = builder.awaitTermination(shutdown.isAwaitTermination()); builder = builder.awaitTermination(shutdown.isAwaitTermination());
builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod()); builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -60,6 +60,7 @@ import static org.mockito.Mockito.mock;
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Camille Vienot * @author Camille Vienot
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Yanming Zhou
*/ */
@ExtendWith(OutputCaptureExtension.class) @ExtendWith(OutputCaptureExtension.class)
@SuppressWarnings("removal") @SuppressWarnings("removal")
@ -124,19 +125,20 @@ class TaskExecutionAutoConfigurationTests {
@Test @Test
void threadPoolTaskExecutorBuilderShouldApplyCustomSettings() { void threadPoolTaskExecutorBuilderShouldApplyCustomSettings() {
this.contextRunner this.contextRunner.withPropertyValues("spring.task.execution.pool.queue-capacity=10",
.withPropertyValues("spring.task.execution.pool.queue-capacity=10", "spring.task.execution.pool.core-size=2", "spring.task.execution.pool.max-size=4",
"spring.task.execution.pool.core-size=2", "spring.task.execution.pool.max-size=4", "spring.task.execution.pool.allow-core-thread-timeout=true", "spring.task.execution.pool.keep-alive=5s",
"spring.task.execution.pool.allow-core-thread-timeout=true", "spring.task.execution.pool.shutdown.accept-tasks-after-context-close=true",
"spring.task.execution.pool.keep-alive=5s", "spring.task.execution.shutdown.await-termination=true", "spring.task.execution.shutdown.await-termination=true",
"spring.task.execution.shutdown.await-termination-period=30s", "spring.task.execution.shutdown.await-termination-period=30s",
"spring.task.execution.thread-name-prefix=mytest-") "spring.task.execution.thread-name-prefix=mytest-")
.run(assertThreadPoolTaskExecutor((taskExecutor) -> { .run(assertThreadPoolTaskExecutor((taskExecutor) -> {
assertThat(taskExecutor).hasFieldOrPropertyWithValue("queueCapacity", 10); assertThat(taskExecutor).hasFieldOrPropertyWithValue("queueCapacity", 10);
assertThat(taskExecutor.getCorePoolSize()).isEqualTo(2); assertThat(taskExecutor.getCorePoolSize()).isEqualTo(2);
assertThat(taskExecutor.getMaxPoolSize()).isEqualTo(4); assertThat(taskExecutor.getMaxPoolSize()).isEqualTo(4);
assertThat(taskExecutor).hasFieldOrPropertyWithValue("allowCoreThreadTimeOut", true); assertThat(taskExecutor).hasFieldOrPropertyWithValue("allowCoreThreadTimeOut", true);
assertThat(taskExecutor.getKeepAliveSeconds()).isEqualTo(5); assertThat(taskExecutor.getKeepAliveSeconds()).isEqualTo(5);
assertThat(taskExecutor).hasFieldOrPropertyWithValue("acceptTasksAfterContextClose", true);
assertThat(taskExecutor).hasFieldOrPropertyWithValue("waitForTasksToCompleteOnShutdown", true); assertThat(taskExecutor).hasFieldOrPropertyWithValue("waitForTasksToCompleteOnShutdown", true);
assertThat(taskExecutor).hasFieldOrPropertyWithValue("awaitTerminationMillis", 30000L); assertThat(taskExecutor).hasFieldOrPropertyWithValue("awaitTerminationMillis", 30000L);
assertThat(taskExecutor.getThreadNamePrefix()).isEqualTo("mytest-"); assertThat(taskExecutor.getThreadNamePrefix()).isEqualTo("mytest-");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,6 +40,7 @@ import org.springframework.util.CollectionUtils;
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Filip Hrisafov * @author Filip Hrisafov
* @author Yanming Zhou
* @since 3.2.0 * @since 3.2.0
*/ */
public class ThreadPoolTaskExecutorBuilder { public class ThreadPoolTaskExecutorBuilder {
@ -54,6 +55,8 @@ public class ThreadPoolTaskExecutorBuilder {
private final Duration keepAlive; private final Duration keepAlive;
private final Boolean acceptTasksAfterContextClose;
private final Boolean awaitTermination; private final Boolean awaitTermination;
private final Duration awaitTerminationPeriod; private final Duration awaitTerminationPeriod;
@ -70,6 +73,7 @@ public class ThreadPoolTaskExecutorBuilder {
this.maxPoolSize = null; this.maxPoolSize = null;
this.allowCoreThreadTimeOut = null; this.allowCoreThreadTimeOut = null;
this.keepAlive = null; this.keepAlive = null;
this.acceptTasksAfterContextClose = null;
this.awaitTermination = null; this.awaitTermination = null;
this.awaitTerminationPeriod = null; this.awaitTerminationPeriod = null;
this.threadNamePrefix = null; this.threadNamePrefix = null;
@ -78,14 +82,15 @@ public class ThreadPoolTaskExecutorBuilder {
} }
private ThreadPoolTaskExecutorBuilder(Integer queueCapacity, Integer corePoolSize, Integer maxPoolSize, private ThreadPoolTaskExecutorBuilder(Integer queueCapacity, Integer corePoolSize, Integer maxPoolSize,
Boolean allowCoreThreadTimeOut, Duration keepAlive, Boolean awaitTermination, Boolean allowCoreThreadTimeOut, Duration keepAlive, Boolean acceptTasksAfterContextClose,
Duration awaitTerminationPeriod, String threadNamePrefix, TaskDecorator taskDecorator, Boolean awaitTermination, Duration awaitTerminationPeriod, String threadNamePrefix,
Set<ThreadPoolTaskExecutorCustomizer> customizers) { TaskDecorator taskDecorator, Set<ThreadPoolTaskExecutorCustomizer> customizers) {
this.queueCapacity = queueCapacity; this.queueCapacity = queueCapacity;
this.corePoolSize = corePoolSize; this.corePoolSize = corePoolSize;
this.maxPoolSize = maxPoolSize; this.maxPoolSize = maxPoolSize;
this.allowCoreThreadTimeOut = allowCoreThreadTimeOut; this.allowCoreThreadTimeOut = allowCoreThreadTimeOut;
this.keepAlive = keepAlive; this.keepAlive = keepAlive;
this.acceptTasksAfterContextClose = acceptTasksAfterContextClose;
this.awaitTermination = awaitTermination; this.awaitTermination = awaitTermination;
this.awaitTerminationPeriod = awaitTerminationPeriod; this.awaitTerminationPeriod = awaitTerminationPeriod;
this.threadNamePrefix = threadNamePrefix; this.threadNamePrefix = threadNamePrefix;
@ -101,8 +106,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder queueCapacity(int queueCapacity) { public ThreadPoolTaskExecutorBuilder queueCapacity(int queueCapacity) {
return new ThreadPoolTaskExecutorBuilder(queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -116,8 +121,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder corePoolSize(int corePoolSize) { public ThreadPoolTaskExecutorBuilder corePoolSize(int corePoolSize) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -131,8 +136,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder maxPoolSize(int maxPoolSize) { public ThreadPoolTaskExecutorBuilder maxPoolSize(int maxPoolSize) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -143,8 +148,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) { public ThreadPoolTaskExecutorBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -154,8 +159,21 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder keepAlive(Duration keepAlive) { public ThreadPoolTaskExecutorBuilder keepAlive(Duration keepAlive) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
}
/**
* Set whether to accept further tasks after the application context close phase has
* begun.
* @param acceptTasksAfterContextClose whether to accept further tasks after the
* application context close phase has begun
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder acceptTasksAfterContextClose(boolean acceptTasksAfterContextClose) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, acceptTasksAfterContextClose, this.awaitTermination,
this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -168,8 +186,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder awaitTermination(boolean awaitTermination) { public ThreadPoolTaskExecutorBuilder awaitTermination(boolean awaitTermination) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -183,8 +201,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder awaitTerminationPeriod(Duration awaitTerminationPeriod) { public ThreadPoolTaskExecutorBuilder awaitTerminationPeriod(Duration awaitTerminationPeriod) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, this.customizers); awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -194,8 +212,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder threadNamePrefix(String threadNamePrefix) { public ThreadPoolTaskExecutorBuilder threadNamePrefix(String threadNamePrefix) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
threadNamePrefix, this.taskDecorator, this.customizers); this.awaitTerminationPeriod, threadNamePrefix, this.taskDecorator, this.customizers);
} }
/** /**
@ -205,8 +223,8 @@ public class ThreadPoolTaskExecutorBuilder {
*/ */
public ThreadPoolTaskExecutorBuilder taskDecorator(TaskDecorator taskDecorator) { public ThreadPoolTaskExecutorBuilder taskDecorator(TaskDecorator taskDecorator) {
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, taskDecorator, this.customizers); this.awaitTerminationPeriod, this.threadNamePrefix, taskDecorator, this.customizers);
} }
/** /**
@ -235,8 +253,8 @@ public class ThreadPoolTaskExecutorBuilder {
public ThreadPoolTaskExecutorBuilder customizers(Iterable<? extends ThreadPoolTaskExecutorCustomizer> customizers) { public ThreadPoolTaskExecutorBuilder customizers(Iterable<? extends ThreadPoolTaskExecutorCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null"); Assert.notNull(customizers, "Customizers must not be null");
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, append(null, customizers)); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator, append(null, customizers));
} }
/** /**
@ -264,8 +282,9 @@ public class ThreadPoolTaskExecutorBuilder {
Iterable<? extends ThreadPoolTaskExecutorCustomizer> customizers) { Iterable<? extends ThreadPoolTaskExecutorCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null"); Assert.notNull(customizers, "Customizers must not be null");
return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize, return new ThreadPoolTaskExecutorBuilder(this.queueCapacity, this.corePoolSize, this.maxPoolSize,
this.allowCoreThreadTimeOut, this.keepAlive, this.awaitTermination, this.awaitTerminationPeriod, this.allowCoreThreadTimeOut, this.keepAlive, this.acceptTasksAfterContextClose, this.awaitTermination,
this.threadNamePrefix, this.taskDecorator, append(this.customizers, customizers)); this.awaitTerminationPeriod, this.threadNamePrefix, this.taskDecorator,
append(this.customizers, customizers));
} }
/** /**
@ -307,6 +326,7 @@ public class ThreadPoolTaskExecutorBuilder {
map.from(this.maxPoolSize).to(taskExecutor::setMaxPoolSize); map.from(this.maxPoolSize).to(taskExecutor::setMaxPoolSize);
map.from(this.keepAlive).asInt(Duration::getSeconds).to(taskExecutor::setKeepAliveSeconds); map.from(this.keepAlive).asInt(Duration::getSeconds).to(taskExecutor::setKeepAliveSeconds);
map.from(this.allowCoreThreadTimeOut).to(taskExecutor::setAllowCoreThreadTimeOut); map.from(this.allowCoreThreadTimeOut).to(taskExecutor::setAllowCoreThreadTimeOut);
map.from(this.acceptTasksAfterContextClose).to(taskExecutor::setAcceptTasksAfterContextClose);
map.from(this.awaitTermination).to(taskExecutor::setWaitForTasksToCompleteOnShutdown); map.from(this.awaitTermination).to(taskExecutor::setWaitForTasksToCompleteOnShutdown);
map.from(this.awaitTerminationPeriod).as(Duration::toMillis).to(taskExecutor::setAwaitTerminationMillis); map.from(this.awaitTerminationPeriod).as(Duration::toMillis).to(taskExecutor::setAwaitTerminationMillis);
map.from(this.threadNamePrefix).whenHasText().to(taskExecutor::setThreadNamePrefix); map.from(this.threadNamePrefix).whenHasText().to(taskExecutor::setThreadNamePrefix);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import static org.mockito.Mockito.spy;
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Filip Hrisafov * @author Filip Hrisafov
* @author Yanming Zhou
*/ */
class ThreadPoolTaskExecutorBuilderTests { class ThreadPoolTaskExecutorBuilderTests {
@ -56,6 +57,12 @@ class ThreadPoolTaskExecutorBuilderTests {
assertThat(executor.getKeepAliveSeconds()).isEqualTo(60); assertThat(executor.getKeepAliveSeconds()).isEqualTo(60);
} }
@Test
void acceptTasksAfterContextCloseShouldApply() {
ThreadPoolTaskExecutor executor = this.builder.acceptTasksAfterContextClose(true).build();
assertThat(executor).hasFieldOrPropertyWithValue("acceptTasksAfterContextClose", true);
}
@Test @Test
void awaitTerminationShouldApply() { void awaitTerminationShouldApply() {
ThreadPoolTaskExecutor executor = this.builder.awaitTermination(true).build(); ThreadPoolTaskExecutor executor = this.builder.awaitTermination(true).build();