Static Scheduling
Spring offers the annotation @Scheduled
to define a task and its corresponding scheduling, e.g., execute this method every 5 minutes. The annotation saves you a great deal of work: in the background, it creates or looks up a scheduler, creates a task which invokes your method, and passes the task to the scheduler with your scheduling arguments (here: every 5 minutes).
Scheduling Parameters
The annotation @Scheduled
allows to specify a fixed delay (in ms), a fixed rate (in ms), or a more flexible cron expression if the first two options are not expressive enough for your use case. The following code snippet shows an implementation of our “every 5 seconds”-example from above:
@Component // or any subtype like @Service public class AnyComponent { private static final Logger log = LoggerFactory.getLogger(AnyComponent.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); @Scheduled(fixedRate = 5000) public void reportCurrentTime() { // visibility is irrelevant: even private is possible log.info("The time is now {}", dateFormat.format(new Date())); } }
Task Method Requirements
The method, which is annotated with @Scheduled
, must fulfill the following requirements:
- The enclosing class of the method must be a Spring component. That is, the class must be annotated with the annotation
@Component
or an annotation which includes@Component
like@Service
, for example. - The method must be void.
- The method must have no parameters.
- The method may be
private
.
Read Parameter Values from a Properties File
If you do not want to specify the delay or the rate directly in the code, you can read it from the configuration context. For this purpose, Spring provides the parameters fixedDelayString
and fixedRateString
. The following example reads the seconds of the delay from the configuration key my.property.fixed.delay.seconds
. If the value is not available or invalid, a default value of 60
is used. Since the delay expects a value in milliseconds, 000
is appended to the read value.
// with a default value of 60 @Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")
Further examples:
// without a default value @Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000") // without appending @Scheduled(fixedDelayString = "${my.property.fixed.delay.milliseconds}") // hard-coded value as string (not recommended due to missing static type checking) @Scheduled(fixedDelayString = "7000")
With these *String
variants, you can define the delay or, respectively, the rate from aproperties file. Note that the value is read only once at startup time. Thus, this approach is still static. You cannot change the value at runtime. We refer to the Javadoc of @Scheduled
for more detailed information on the parameters.
Dynamic Scheduling
If you need to read your scheduling arguments dynamically, that is, at runtime, then you @Scheduled
is not sufficient. Instead, your can use Spring’s interface TaskScheduler
. Declare a field with this type and annotate it with Spring’s @Autowired
annotation. Then, you can pass a dynamically created task to the scheduler and specify whether it should be executed once or repeatable with a fixed delay or at a fixed rate. We refer to the documentation of the TaskScheduler
for more information.
Sources
- Getting Started with static scheduling using
@Scheduled
,fixedDelay
,fixedRate
,@EnableScheduling
: https://spring.io/guides/gs/scheduling-tasks/ - Documentation of
@Scheduled
: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-annotation-support-scheduled - Javadoc of
@Scheduled
: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html - Example for using
fixedDelayString
: https://stackoverflow.com/a/31109486 - Documentation of
TaskScheduler
: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-task-scheduler