Skip to main content
Advertisement

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.

Advertisement