2.8 Scheduling (@Scheduled)
Use @Scheduled for periodic tasks: regular batch jobs, stats aggregation, cache cleanup, etc.
Reference: Spring Boot 3.2.x
1. @EnableScheduling
@SpringBootApplication
@EnableScheduling
public class Application { ... }
2. Fixed Rate / Delay
@Component
public class StatsScheduler {
@Scheduled(fixedRate = 60000) // every 60s (regardless of previous completion)
public void collectStats() {
// collect stats
}
@Scheduled(fixedDelay = 60000) // 60s after previous completion
public void cleanup() {
// cleanup
}
@Scheduled(initialDelay = 10000, fixedRate = 60000) // every 60s, starting 10s after startup
public void sync() {
// sync
}
}
- fixedRate: Interval from start time
- fixedDelay: Interval after previous task completion
- initialDelay: Delay before first run (ms)
3. Cron
Use cron for complex day-of-week / time schedules.
@Scheduled(cron = "0 0 2 * * ?") // every day at 2 AM
public void dailyReport() { ... }
@Scheduled(cron = "0 */10 * * * ?") // every 10 minutes
public void everyTenMinutes() { ... }
Format: second minute hour day month weekday [year]
- Weekday: 0–7 (0 and 7 = Sunday), MON–SUN also accepted
- Spring uses 6 fields (year omitted)
4. Disable by Profile / Property
Use @Profile or @ConditionalOnProperty to run schedules only in certain environments.
@Component
@Profile("!test")
@ConditionalOnProperty(name = "app.scheduler.enabled", havingValue = "true", matchIfMissing = true)
public class StatsScheduler { ... }
5. Single Instance (Distributed)
With multiple servers, use ShedLock or DB/Redis-based lock to prevent duplicate execution. Spring's default @Scheduled does not coordinate across instances.
tip
For long-running tasks, limit the thread pool size with TaskScheduler and combine with @Async to run on a separate thread if needed.