Le format cron de Spring
Une expression Spring compte six champs : seconde, minute, heure, jour du mois, mois et jour de la semaine, par exemple 0 0 9 * * MON-FRI pour 09:00 en semaine. Dimanche s’écrit 0, 7 ou SUN. Depuis Spring Framework 5.3, l’analyseur comprend aussi L, W et # dans les champs de jour, ainsi que des macros comme @hourly et @daily.
Fuseau horaire de @Scheduled
Par défaut, les expressions sont évaluées dans le fuseau par défaut du serveur. Définissez l’attribut zone, par exemple @Scheduled(cron = "0 0 2 * * *", zone = "Europe/Paris"), pour rendre la planification indépendante de l’hôte. Choisissez le même fuseau dans l’outil pour prévisualiser les exécutions.
Spring ou Quartz ?
Les expressions Spring ressemblent à celles de Quartz mais diffèrent sur des détails : pas de champ année, dimanche vaut 0 et non 1, et « ? » est accepté sans être obligatoire. Quand les deux champs de jour sont restreints, Spring exige que les deux correspondent. Le convertisseur affiche l’équivalent Quartz lorsqu’il existe.
Activer la planification
Les méthodes cron ne s’exécutent que si la planification est activée avec @EnableScheduling. Par défaut, Spring utilise un seul thread : une tâche longue retarde toutes les autres ; configurez un ThreadPoolTaskScheduler ou spring.task.scheduling.pool.size si vous avez plusieurs tâches. En cluster, chaque instance déclenche le même cron : utilisez un verrou comme ShedLock si une tâche ne doit tourner qu’une fois.
Questions fréquentes
- Pourquoi Spring exige-t-il six champs ?
- Spring a besoin d’un champ secondes. Ajoutez 0 devant une expression crontab à cinq champs : 0 */5 * * * * s’exécute toutes les cinq minutes.
- Comment désactiver une tâche @Scheduled cron ?
- Utilisez la valeur spéciale "-" (Scheduled.CRON_DISABLED), généralement via un espace réservé de propriété.
- Spring gère-t-il le dernier jour du mois ?
- Oui, depuis la 5.3 : 0 0 0 L * * s’exécute à minuit le dernier jour de chaque mois.
- Puis-je lire l’expression cron depuis la configuration ?
- Oui, par exemple @Scheduled(cron = "${jobs.cleanup.cron}"), pour adapter la planification à chaque environnement.