๐ด The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}โก Quick Fix Works 80% of the time
Define a ThreadPoolTaskScheduler bean in your @Configuration class.
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5);
return scheduler;
}๐ง Why this Happens
Tap to expand the deep technical explanation
Spring's scheduling engine needs a `TaskScheduler` to execute `@Scheduled` methods. By default, Spring Boot auto-configures one. However, if you customized your context, or you explicitly `@Autowired` a `TaskScheduler` in a non-standard way, Spring might fail to find the default bean.
The HITEC City Parking Spot Analogy:
A train station has a timetable (@Scheduled), but they forgot to hire a dispatcher (TaskScheduler). The trains don't know when to leave because no one is directing them.
๐ How to Reproduce Confirm this is your error
Create a `@Service` with `@Autowired private TaskScheduler scheduler;`. Do not define a `@Bean` for it and do not use `@EnableScheduling`. Run the app.
๐ ๏ธ Solutions (5 Ways to Fix)
Define a ThreadPoolTaskScheduler bean
๐ Use this to explicitly provide the scheduler.
Creating a `ThreadPoolTaskScheduler` bean gives Spring a concrete scheduler to inject.
@Configuration
public class SchedulerConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5);
scheduler.setThreadNamePrefix("my-scheduler-");
return scheduler;
}
}Add @EnableScheduling
๐ Use this if you are using @Scheduled but forgot to turn it on.
This annotation activates the scheduling engine and auto-registers a default TaskScheduler if one isn't found.
@SpringBootApplication
@EnableScheduling
public class Application { ... }Use ScheduledExecutorService instead
๐ Use this if you want to use standard Java concurrency instead of Spring's interface.
Inject the standard Java `ScheduledExecutorService` instead of Spring's `TaskScheduler`.
@Bean
public ScheduledExecutorService scheduledExecutorService() {
return Executors.newScheduledThreadPool(5);
}Fix conflicting bean names
๐ Use this if you have multiple scheduler beans.
If you defined two TaskScheduler beans, Spring gets confused. Use @Primary on the main one.
@Bean
@Primary
public TaskScheduler primaryScheduler() { ... }Do not autowire TaskScheduler manually
๐ Use this if you are overcomplicating your code.
Usually, you don't need to inject TaskScheduler. Just put @Scheduled on your methods and let Spring handle it.
// Just use the annotation:
@Scheduled(fixedRate = 5000)
public void runJob() { ... }
// Remove @Autowired TaskScheduler;๐ Version Notes
Auto-configures a default scheduler if needed.
Stricter bean resolution, fails fast if multiple candidates exist without @Primary.
๐ก๏ธ How to Prevent This Next Time
If you need custom thread pooling for scheduled tasks, always define a single, explicit `ThreadPoolTaskScheduler` bean.