Why do we need scheduling?
Scheduling is needed if you want to automate the repetition of a task at specific intervals or particular date. You could of course manually watch the time and execute your task, albeit an inefficient task. Who wants to watch the computer every 3 seconds just to hit the Enter key? No one.
The work
We want to run the following sample class at specific intervals:
The task that we're interested is inside the work() method. This example is based on Mark Fisher's example at Task Scheduling Simplifications in Spring 3.0. This method retrieves the thread name, prints the starting and beginning of the method, simulates work by putting the thread in sleep for 10 seconds.
To schedule this using Spring's annotation support, we'll use the @Scheduled annotation.
The @Scheduled Annotation
Spring 3.0 also adds annotation support for both task scheduling and asynchronous method execution.... The @Scheduled annotation can be added to a method along with trigger metadata.To enable this annotation we need to add the annotation-driven element:
Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
You also need to add the component-scan element. We didn't enable it here since it's already added in the applicationContext.xml (see the accompanying source code at the end of this tutorial)
Let's examine an actual example. We'll create a new class SyncWorker that implements a Worker interface.
Worker
SyncWorker
This worker is synchronous which means if we have to call this worker 10 times, it will block the other workers. They cannot start immediately until the first one is finished. We didn't do anything to make this implementation synchronous. It's the default.
The class that calls this SyncWorker is a scheduler service.
Notice the @Scheduled annotation in the doSchedule() method. This tells Spring to mark this method for task scheduling. Inside the @Scheduled, there's a metadata that describes when the method should be triggered. The following metadata all have the same value (5 seconds) but they are interpreted differently:
fixedDelay=5000 fixedRate=5000 cron="*/5 * * * * ?"fixedDelay: An interval-based trigger where the interval is measured from the completion time of the previous task. fixedRate: An interval-based trigger where the interval is measured from the start time of the previous task. cron: A cron-based trigger Running the application gives us the following logs:
Notice how the tasks are run sequentially every 5 seconds.
What if we want to run the workers asynchronously, meaning we don't want to wait for worker 1 to finish before we start worker 2, or worker 3, and so forth? There are valid reasons like efficient use of physical resources and time.
To make a worker asychronous, we add the @Async annotation in the method that needs to be asychronous.
The @Async Annotation
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.To enable this annotation we use the same annotation-driven element.
Source: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Let's examine an actual example. We'll create a new class AsyncWorker that implements the Worker interface earlier.
AsyncWorker
This worker is asychronous. The caller (the scheduler service) will return immediately upon invocation.
The class that calls this AsyncWorker is the same scheduler service we had earlier. We
just need to change the value of @Qualifier
Same implementation, except for the asyncWorker reference. It's unbelievably easy.
Running the application gives us the following logs:
Notice how the tasks are run asynchronously.
One final note. Let's examine the XML file that contains the annotation-driven element:
Notice I have added two attributes in the annotation-driven element: executor and scheduler. Both are references to the beans declared at the bottom of the file. The ids of these beans become the default thread name prefixes. See below (taskScheduler-1 and executorWithPoolSizeRange-1):
That's it. We've added scheduling support using the @Scheduled annotation, and asychronous support using the @Async annotation. To see the output, please check the logs. Feel free to modify the MVC app to fit your needs. You might wanna try integrating a web service with scheduling and show the results via MVC. The welcome page is accesible at
http://localhost:8080/spring-mvc-task-scheduling-annotation/krams/main/welcomeThe best way to learn further is to try the actual application.
Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-scheduling/
You can download the project as a Maven build. Look for the spring-mvc-task-scheduling-annotation.zip in the Download sections.
You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
If you need to know more about Task Scheduling in Spring 3.0, please visit the following links:
- Task Scheduling Simplifications in Spring 3.0
- Spring Framework 3 Reference, Chapter 25. Task Execution and Scheduling
Share the joy:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |

