In this quick article, Spring provides annotation support for both task scheduling and asynchronous method execution so we’re going to explore the Spring Scheduling Annotations.
This article is part of a series:
Let's explore task scheduling and asynchronous annotations from the org.springframework.scheduling.annotation package.
The @Scheduled annotation is added to a method along with some information about when to execute it, and Spring takes care of the rest.
For example, the following method would be invoked every 5 seconds with a fixed delay, meaning that the period will be measured from the completion time of each preceding invocation.
@Scheduled(fixedDelay=5000) public void doSomething() { // something that should execute periodically }
If a fixed rate execution is desired, simply change the property name specified within the annotation. The following would be executed every 5 seconds measured between the successive start times of each invocation.
@Scheduled(fixedRate=5000) public void doSomething() { // something that should execute periodically }
For fixed-delay and fixed-rate tasks, an initial delay may be specified indicating the number of milliseconds to wait before the first execution of the method.
@Scheduled(initialDelay=1000, fixedRate=5000) public void doSomething() { // something that should execute periodically }
If simple periodic scheduling is not expressive enough, then a cron expression may be provided. For example, the following will only execute on weekdays.
@Scheduled(cron="*/5 * * * * MON-FRI") public void doSomething() { // something that should execute on weekdays only }
@EnableScheduling annotation is used to enable scheduling in the application. We also have to use it in conjunction with @Configuration:
@Configuration @EnableScheduling public class Appconfig{}
As a result, we can now run methods periodically with @Scheduled.
The @Async annotation can be provided on a method so that invocation of that method will occur asynchronously. In other words, the caller will return immediately upon invocation and the actual execution of the method will occur in a task that has been submitted to a Spring TaskExecutor. In the simplest case, the annotation may be applied to a void-returning method.
@Async void doSomething() { // this will be executed asynchronously }
Unlike the methods annotated with the @Scheduled annotation, these methods can expect arguments, because they will be invoked in the "normal" way by callers at runtime rather than from a scheduled task being managed by the container.
For example, the following is a legitimate application of the @Async annotation.
@Async void doSomething(String s) { // this will be executed asynchronously }
Even methods that return a value can be invoked asynchronously. However, such methods are required to have a Future typed return value. This still provides the benefit of asynchronous execution so that the caller can perform other tasks prior to calling get() on that Future.
@Async Future<String> returnSomething(int i) { // this will be executed asynchronously }
@Async cannot be used in conjunction with lifecycle callbacks such as @PostConstruct. To asynchronously initialize Spring beans you currently have to use a separate initializing Spring bean that invokes the @Async annotated method on the target then.
public class SampleBeanImpl implements SampleBean { @Async void doSomething() { // ... } } public class SampleBeanInitializer { private final SampleBean bean; public SampleBeanInitializer(SampleBean bean) { this.bean = bean; } @PostConstruct public void initialize() { bean.doSomething(); } }
With this annotation, we can enable asynchronous functionality in Spring. We must use it with @Configuration:
@Configuration @EnableAsync public class AppConfig{}
Now, that we enabled asynchronous calls, we can use @Async to define the methods supporting it.
We can use this annotation to specify multiple @Scheduled rules:
@Schedules({ @Scheduled(fixedRate = 10000), @Scheduled(cron = "0 * * * * MON-FRI") }) void checkVehicle() { // ... }