TaskExecutorConfigurations Class — spring-boot Architecture
Architecture documentation for the TaskExecutorConfigurations class in TaskExecutorConfigurations.java from the spring-boot codebase.
Entity Profile
Relationship Graph
Source Code
core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java lines 64–286
class TaskExecutorConfigurations {
private static @Nullable TaskDecorator getTaskDecorator(ObjectProvider<TaskDecorator> taskDecorator) {
List<TaskDecorator> taskDecorators = taskDecorator.orderedStream().toList();
if (taskDecorators.size() == 1) {
return taskDecorators.get(0);
}
return (!taskDecorators.isEmpty()) ? new CompositeTaskDecorator(taskDecorators) : null;
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ContextSnapshot.class)
static class TaskExecutorContextPropagationConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.task.execution.propagate-context", havingValue = "true")
ContextPropagatingTaskDecorator contextPropagatingTaskDecorator() {
return new ContextPropagatingTaskDecorator();
}
}
@Configuration(proxyBeanMethods = false)
@Conditional(OnExecutorCondition.class)
@Import({ AsyncConfigurerWrapperConfiguration.class, AsyncConfigurerConfiguration.class })
static class TaskExecutorConfiguration {
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
@ConditionalOnThreading(Threading.VIRTUAL)
SimpleAsyncTaskExecutor applicationTaskExecutorVirtualThreads(SimpleAsyncTaskExecutorBuilder builder) {
return builder.build();
}
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
@Lazy
@ConditionalOnThreading(Threading.PLATFORM)
ThreadPoolTaskExecutor applicationTaskExecutor(ThreadPoolTaskExecutorBuilder threadPoolTaskExecutorBuilder) {
return threadPoolTaskExecutorBuilder.build();
}
}
@Configuration(proxyBeanMethods = false)
static class ThreadPoolTaskExecutorBuilderConfiguration {
@Bean
@ConditionalOnMissingBean
ThreadPoolTaskExecutorBuilder threadPoolTaskExecutorBuilder(TaskExecutionProperties properties,
ObjectProvider<ThreadPoolTaskExecutorCustomizer> threadPoolTaskExecutorCustomizers,
ObjectProvider<TaskDecorator> taskDecorator) {
TaskExecutionProperties.Pool pool = properties.getPool();
ThreadPoolTaskExecutorBuilder builder = new ThreadPoolTaskExecutorBuilder();
builder = builder.queueCapacity(pool.getQueueCapacity());
builder = builder.corePoolSize(pool.getCoreSize());
builder = builder.maxPoolSize(pool.getMaxSize());
builder = builder.allowCoreThreadTimeOut(pool.isAllowCoreThreadTimeout());
builder = builder.keepAlive(pool.getKeepAlive());
builder = builder.acceptTasksAfterContextClose(pool.getShutdown().isAcceptTasksAfterContextClose());
TaskExecutionProperties.Shutdown shutdown = properties.getShutdown();
builder = builder.awaitTermination(shutdown.isAwaitTermination());
builder = builder.awaitTerminationPeriod(shutdown.getAwaitTerminationPeriod());
builder = builder.threadNamePrefix(properties.getThreadNamePrefix());
builder = builder.customizers(threadPoolTaskExecutorCustomizers.orderedStream()::iterator);
builder = builder.taskDecorator(getTaskDecorator(taskDecorator));
return builder;
}
}
@Configuration(proxyBeanMethods = false)
static class SimpleAsyncTaskExecutorBuilderConfiguration {
private final TaskExecutionProperties properties;
private final ObjectProvider<SimpleAsyncTaskExecutorCustomizer> taskExecutorCustomizers;
private final ObjectProvider<TaskDecorator> taskDecorator;
SimpleAsyncTaskExecutorBuilderConfiguration(TaskExecutionProperties properties,
ObjectProvider<SimpleAsyncTaskExecutorCustomizer> taskExecutorCustomizers,
ObjectProvider<TaskDecorator> taskDecorator) {
this.properties = properties;
this.taskExecutorCustomizers = taskExecutorCustomizers;
this.taskDecorator = taskDecorator;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnThreading(Threading.PLATFORM)
SimpleAsyncTaskExecutorBuilder simpleAsyncTaskExecutorBuilder() {
return builder();
}
@Bean(name = "simpleAsyncTaskExecutorBuilder")
@ConditionalOnMissingBean
@ConditionalOnThreading(Threading.VIRTUAL)
SimpleAsyncTaskExecutorBuilder simpleAsyncTaskExecutorBuilderVirtualThreads() {
return builder().virtualThreads(true);
}
private SimpleAsyncTaskExecutorBuilder builder() {
SimpleAsyncTaskExecutorBuilder builder = new SimpleAsyncTaskExecutorBuilder();
builder = builder.threadNamePrefix(this.properties.getThreadNamePrefix());
builder = builder.customizers(this.taskExecutorCustomizers.orderedStream()::iterator);
builder = builder.taskDecorator(getTaskDecorator(this.taskDecorator));
TaskExecutionProperties.Simple simple = this.properties.getSimple();
builder = builder.cancelRemainingTasksOnClose(simple.isCancelRemainingTasksOnClose());
builder = builder.rejectTasksWhenLimitReached(simple.isRejectTasksWhenLimitReached());
builder = builder.concurrencyLimit(simple.getConcurrencyLimit());
TaskExecutionProperties.Shutdown shutdown = this.properties.getShutdown();
if (shutdown.isAwaitTermination()) {
builder = builder.taskTerminationTimeout(shutdown.getAwaitTerminationPeriod());
}
return builder;
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(AsyncConfigurer.class)
static class AsyncConfigurerWrapperConfiguration {
@Bean
static BeanPostProcessor applicationTaskExecutorAsyncConfigurerBeanPostProcessor(
ObjectProvider<BeanFactory> beanFactory) {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AsyncConfigurer asyncConfigurer
&& !(bean instanceof ApplicationTaskExecutorAsyncConfigurer)) {
return new ApplicationTaskExecutorAsyncConfigurer(beanFactory.getObject(), asyncConfigurer);
}
return bean;
}
};
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(AsyncConfigurer.class)
static class AsyncConfigurerConfiguration {
@Bean
ApplicationTaskExecutorAsyncConfigurer applicationTaskExecutorAsyncConfigurer(BeanFactory beanFactory) {
return new ApplicationTaskExecutorAsyncConfigurer(beanFactory, null);
}
}
@Configuration(proxyBeanMethods = false)
static class BootstrapExecutorConfiguration {
@Bean
static BeanFactoryPostProcessor bootstrapExecutorAliasPostProcessor() {
return (beanFactory) -> {
boolean hasBootstrapExecutor = beanFactory
.containsBean(ConfigurableApplicationContext.BOOTSTRAP_EXECUTOR_BEAN_NAME);
boolean hasApplicationTaskExecutor = beanFactory
.containsBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME);
if (!hasBootstrapExecutor && hasApplicationTaskExecutor) {
beanFactory.registerAlias(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME,
ConfigurableApplicationContext.BOOTSTRAP_EXECUTOR_BEAN_NAME);
}
};
}
}
static class OnExecutorCondition extends AnyNestedCondition {
OnExecutorCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnMissingBean(Executor.class)
private static final class ExecutorBeanCondition {
}
@ConditionalOnProperty(value = "spring.task.execution.mode", havingValue = "force")
private static final class ModelCondition {
}
}
/**
* {@link AsyncConfigurer} implementation that delegates to the user-defined
* {@link AsyncConfigurer} instance, if any. Consistently use the executor named
* {@value TaskExecutionAutoConfiguration#APPLICATION_TASK_EXECUTOR_BEAN_NAME} in the
* absence of a custom executor.
*/
static class ApplicationTaskExecutorAsyncConfigurer implements AsyncConfigurer {
private final BeanFactory beanFactory;
private final @Nullable AsyncConfigurer delegate;
ApplicationTaskExecutorAsyncConfigurer(BeanFactory beanFactory, @Nullable AsyncConfigurer delegate) {
this.beanFactory = beanFactory;
this.delegate = delegate;
}
@Override
public Executor getAsyncExecutor() {
Executor executor = (this.delegate != null) ? this.delegate.getAsyncExecutor() : null;
return (executor != null) ? executor : getApplicationTaskExecutor();
}
@Override
public @Nullable AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (this.delegate != null) ? this.delegate.getAsyncUncaughtExceptionHandler() : null;
}
private Executor getApplicationTaskExecutor() {
return this.beanFactory.getBean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME,
Executor.class);
}
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free