I want to use a custom @Async("singleThreadExecutor") for only one of my methods. All others should still be using the applicationTaskExecutor.

Problem: as soon as I provide my own TaskExecutor, the default TaskExecutionAutoConfiguration.applicationTaskExecutor() will not be executed anymore. Resulting that all of my tasks will be executed with my custom executor, as the default applicationTaskExecutor will be missing then.

I don't know if this is a bug or a feature. But I only discovered this by accident, and without, all my my application tasks would be running unexpectedly on my custom "single queue discard others" executor.

@Configuration
public class Config {
    @Bean
    public TaskExecutor singleThreadExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(1);
        taskExecutor.setMaxPoolSize(1);
        taskExecutor.setQueueCapacity(1);
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        return taskExecutor;
    }
}

Comment From: snicoll

Yes this is a feature. Like everything in Spring Boot, if you express an opinion for something, the auto-configuration will back off. Looking at the auto-configuration report will tell you that we haven't auto-configured an executor because the user configuration defines one already.

If you need to create a custom executor and use the auto-configured one, you can inject a TaskExecutorBuilder as explained in the documentation.

Going forward, please ask such questions on StackOverflow.

Comment From: membersound

I still think this is a bit counter-intuitive.

Imagine I provide an additional TranscationManager for my application, that I use with @Transactional("customTx"). This would not prevent Spring from initializing a default TransactionManager, which is still used for all other @Transactional methods.

This behavior makes more sense to me, than just neglecting the default TaskExecutor, and instead running all normal @Async methods with the executor that actually was created to be used by @Async("singleThreadExecutor").

Comment From: snicoll

Imagine I provide an additional TranscationManager for my application, that I use with @Transactional("customTx"). This would not prevent Spring from initializing a default TransactionManager, which is still used for all other @Transactional methods.

Actually it would. The behavior that I've described above is the safest bet IMO. You may feel this way now and being annoyed next time that creating your own X does not prevent the auto-configuration to create one. The pattern of exposing a builder (as I've explained) gives you easily back what the auto-configuration would do.

Comment From: membersound

Oh okay, than I was on the wrong track about @Transactional. If it's consistent throughout all annotations regarding auto configuration, then yes of course this makes sense. And indeed it's no problem to simply instantiate the default executor based on the builder bean, that's true.