Spring provides excellent support for both task scheduling and asynchronous method execution based on cron expression using @Scheduled
annotation. The @Scheduled annotation can be added to a method along with trigger metadata.
In this post, I will show the means to use @Scheduled
feature in 4 different ways.
Read More : Spring timer tasks
Table of Contents 1. @Scheduled Annotation 2. Fixed delay or Fixed rate 3. Cron expressions 4. Cron expression from properties file 5. Cron expression in context configuration
1. Spring @Scheduled Annotation
@Scheduled
annotation is used for task scheduling. The trigger information needs to be provided along with this annotation.
1.1. fixedDelay vs fixedRate vs cron
You can use the properties fixedDelay
/fixedRate
/cron
to provide the triggering information. where –
- fixedRate makes Spring run the task on periodic intervals even if the last invocation may be still running.
- fixedDelay specifically controls the next execution time when the last execution finishes.
- cron is a feature originating from Unix cron utility and has various options based on your requirements.
Example usage can be as below:
@Scheduled(fixedDelay =30000) public void demoServiceMethod () {... } @Scheduled(fixedRate=30000) public void demoServiceMethod () {... } @Scheduled(cron="0 0 * * * *") public void demoServiceMethod () {... }
1.2. How to enable @Scheduled annotation
To use @Scheduled
in your spring application, you must first define below xml namespace and schema location definition in your applicationConfig.xml
file. Also add task:annotation-driven
to enable annotation based task scheduling.
xmlns:task="http://www.springframework.org/schema/task" http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd <task:annotation-driven>
Above additions are necessary because we will be using annotation based configurations.
1.3. Using @Scheduled annotation
Next step is to create a class and a method inside the class like below:
public class DemoService { @Scheduled(cron="*/5 * * * * ?") public void demoServiceMethod() { System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date()); } }
In above example –
- Using
@Scheduled
annotation would in turn make Spring container understand that the method underneath this annotation would run as a job. - Remember that the methods annotated with
@Scheduled
should not have parameters passed to them. - They should not return any values too.
- If you want the external objects to be used within your @Scheduled methods, you should inject them into the
DemoService
class using autowiring rather than passing them as parameters to the@Scheduled
methods.
2. @Scheduled with fixed delay or fixed rate
In this method, fixedDelay attribute is used with @Scheduled
annotation. Alternatively, fixedRate can also be used.
A sample class will look like this:
package com.howtodoinjava.service; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; public class DemoServiceBasicUsageFixedDelay { @Scheduled(fixedDelay = 5000) //@Scheduled(fixedRate = 5000) //Or use this public void demoServiceMethod() { System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date()); } }
And application configuration will look like this:
< ?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <task:annotation-driven /> <bean id="demoServiceBasicUsageFixedDelay" class="com.howtodoinjava.service.DemoServiceBasicUsageFixedDelay"></bean> </beans>
3. @Scheduled with cron expression
In this method, cron
attribute is used with @Scheduled
annotation. Value of this attribute must be a cron expression.
A sample class will look like this:
package com.howtodoinjava.service; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; public class DemoServiceBasicUsageCron { @Scheduled(cron="*/5 * * * * ?") public void demoServiceMethod() { System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date()); } }
And application configuration will look like this:
< ?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <task:annotation-driven /> <bean id="demoServiceBasicUsageCron" class="com.howtodoinjava.service.DemoServiceBasicUsageCron"></bean> </beans>
4. Cron expression from properties file
In this method, cron
attribute is used with @Scheduled
annotation. Value of this attribute must be a cron expression as in previous method, BUT, this cron expression will be defined in a properties file and key of related property will be used in @Scheduled
annotation.
This will decouple the cron expression from source code, thus making changes easy.
package com.howtodoinjava.service; import java.util.Date; import org.springframework.scheduling.annotation.Scheduled; public class DemoServicePropertiesExample { @Scheduled(cron = "${cron.expression}") public void demoServiceMethod() { System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date()); } }
And application configuration will look like this:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <task:annotation-driven /> <util:properties id="applicationProps" location="application.properties" /> <context:property-placeholder properties-ref="applicationProps" /> <bean id="demoServicePropertiesExample" class="com.howtodoinjava.service.DemoServicePropertiesExample"></bean> </beans>
5. Cron expression in context configuration
In this method, cron expression is configured in properties file, and job scheduling is configured in configuration file using property key for cron expression. Major change is that you do not need to use @Scheduled
annotation on any method. Method configuration is also done in application configuration file.
A sample class will look like this:
package com.howtodoinjava.service; import java.util.Date; public class DemoServiceXmlConfig { public void demoServiceMethod() { System.out.println("Method executed at every 5 seconds. Current time is :: "+ new Date()); } }
And application configuration will look like this:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util/ http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/task/ http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <task:annotation-driven /> <util:properties id="applicationProps" location="application.properties" /> <context:property-placeholder properties-ref="applicationProps" /> <bean id="demoServiceXmlConfig" class="com.howtodoinjava.service.DemoServiceXmlConfig" /> <task:scheduled-tasks> <task:scheduled ref="demoServiceXmlConfig" method="demoServiceMethod" cron="#{applicationProps['cron.expression']}"></task:scheduled> </task:scheduled-tasks> </beans>
Let me know if I am missing anything.
Happy Learning !!
Reference:
http://forum.springsource.org/showthread.php?83053-Feature-Scheduled-with-Value-cron-expression
I want run scheduler every 1 min . First time scheduler started and it take more than 1 min time i don’t want to start scheduler next min until first process is completed. is their any way that we can achieve in spring boot.
is there any way we can stop this job in case job get into hung state ?
My job is running as soon as i start the application for the first time without entering into my scheduler.
After the first time, it is entering into scheduler. What needs to be done for the job to enter the scheduler from the first time ?
How can I pass cron and timezone dynamically.
thanks in advance
Which Spring jar we need to use for above use case
How to schedule tasks dynamically. For example : If my 1st task runs after 5 minutes, the next will run after 4 minutes, the next will run after 1 minute and so on…
Thanks Lokesh, great article.
I am using @Scheduled in spring boot application, to send the new news after every 5minutes, find below code snippet:
But the problem is:
*** The code is not working on AWS EC2 windows server 2016 instance, but same is working on Elastic Beanstalk instance. There is no any log or exception printed so unable to trace it out.
Can you please help me? Many thanks in advance.
hi,
i want to change my status yes or no in database periodically. how can i use scheduler. please give me code.
I am trying to parameterize cron expression to a properties file using method 3 explained above. I am getting following exception “WARNING: Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘springScheduleCronExample’: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method ‘cronJob’: Cron expression must consist of 6 fields (found 1 in “${cron.expression}”)”
Here is my applicationContext.xml
My SpringSchedulerCronExample.java
And my application.properties are under src/main/resources
cron.expression=*/5 * * * * ?
Somehow your properties are not resolved.
${cron.expression}
should have been resolved. Check if file properties file is in classes folder after building source code.How to run this maven project
Is there a way to run a function before the application shuts down where I can clear the queue that I am using in the Cron defined by @Scheduled annotation?
Great article Lokesh!!
Do we always need to write a main method to execute these jobs?
What if I want it to trigger without any manual intervention?
main() method is not mandatory.
can u post an example for the same……please
And how to set MISFIRE_INSTRUCTION ?
good job! thanks
Hi Lokesh,
I am using @Scheduled method in one of my spring boot application. In this @Scheduled method I am calling another method. My requirement is to stop the execution of this @Scheduled method once this called method’s execution is over.
Any pointers / sample code for this to achieve the functionality?
Regards,
Nitin
Hi I have a spring mvc (4.2) based GUI web application to which I want to add a spring based scheduler. I am using the approach mentioned in method #2. What I have observed is that the scheduler does not run automatically when the application is deployed. However the scheduler starts only after the web application GUI is launched. Any idea how to start the scheduler when the web application is deployed?
Hi,
Is it possible to add value from for example .properties to @Scheduled?
I have been trying this, and its seems impossible?
-AL
I also tried a lot, but seems the path is hidden somewhere.. 🙂 I will do more research on it now.
Great, thanks a lot!
I spent almost 5 hours on it 🙂 Great portal, this goes to favorites!!!
Thanks for quick answer!
Glad, you liked it.
Hi,
My Cron trigger has been scheduled on 0 0 21 7 1/7 ? Now my requirement is never execute this trigger in future, what kind of expression i can provide?
Check this :
https://help.ubuntu.com/community/CronHowto
I have to Add some data from a http:URL on a regular basis , For That what should I Can do in Scheduler???
Thanks a lot for such useful information. I just tried one method but it’s really easy to understand.
A Silly question (I started on Spring only before 2 days)
Why do we need to give the class as a in application context file ? I was trying the annotated way.
If you are using java annotation config, then you don’t need to define the beans in context file.
It does not start the Job if I don’t provide it as a bean.
Read more about java config here: https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/creating-bean-definitions.html
I could not reply on the same day, but I had not annotated my Job class with @Component so it was giving exception while doing injection. It worked fine later.
Thanks
Thanks for updating Piyush. Appreciated.
Hi,
Have a question on whether to go for Task Execution and Scheduling i.e. @Async of spring or dedicated AMQP such as HornetQ
Load can be varying, burst of request can occur. How to handle such use case.
I will bet on HornetQ. It performs real well under load. Not sure of @Async capability under load. You need to load test it first.
Hi,
I am new to spring stuff.
I am trying to setup an example as per your excellent blog post. But was wondering how would i get about executing this example.
Do i need to create a run configuration in eclipse?
Or do i just create an extra class with void main() and then just execute that one to see delayed scheduled call?
Regards
Hassan
The sourcecode of the project is attached in last of post. Please see the classes to to execute the examples in “test” package.
Lokesh, I got a simple question, Im trying an example with fixedDelay=5000, to print a simple message displaying the current date, question is, why is printing it twice every 5 seconds??
Hope you can help me. Kudos.
Hi Lokesh
Could you please help about how to deploy and test this jar in any server.
I can’t see the arcticle.
Where is it ?
Sorry for this. I was trying some modification on my blog. I have reverted the code. Please do hard refresh (CTRL+F5).
Hi Lokesh,
Can you please suggest how can i deploy this jar in any server.
Thanks in advance
Hi Lokesh,
I am using scheduler to check on a database table, every 5 minutes. If tables gets updated I will be executing some business function and do not want to check on that table further. How could we stop the scheduler or not to make it check further?
Set/Save a flag in config table in database and mark it down when condition met. Everytime scheduler run, it should check the flag first before executing further.
Thanks Lokesh. I have implemented it the same way and in addition I am using a static class variable to avoid calling database multiple times. I was expecting to have some ‘disable scheduling for current method’ kind of property from spring API. However I am fine with this too. Thanks again!!
how will i schedule for a particular day say 10-th of every 2 months? Also for DB transactions with scheduler, which will be the better way?
How to shutdown some job with fixed interval. I don’t want restart tomcat I want call some URL pass the parameters and shutdown scheduler is it possible?
I really do not think, that it is so simple. The most close work-around which comes right now into my mind is “Trigger” interface. Read more in linked document. Use it to delay the execution as long as never.
excellent guide. very helpful
This is exactly what I was looking for. Thanks!
Thanx mate. It was really helpful 🙂
i am trying to use @Scheduled(fixedRate=86400000) to schedule it every 24 hrs.
what if my server (tomcat) is shutdown (for example another deployment), will it run in every 24hrs.
NO. It will not.
nice tutorial.. thank you for sharing
Hi, Lokesh. Thank you for sharing!
I have one more question: which are the best ways to combine these solutions with the @Async annotation?
Thank you!
@Async annotation helps in asynchronous processing, means you do not want to wait for completion of task. Use it when you have a valid usecase. Putting @Async annotation is enough.
You’re completely right, Lokesh! Thank you for your quick response.
Hi Lokesh,
I am new to spring..can you please tell me how to implement above scheduler in my application..how to pass parameter to a method if I schedule it.
If I am understanding correctly, you want to schedule based on user preferences which multiple users can have differently, and schedule information stored in database. If it is your case, use something else e.g. quartz.
Hi Lokesh,
I am using config in my application like below
I want to modify fixed-delay parameter on the fly from a JSP page , is there a way to get and set fixed-delay programatically and modify it on the fly?
Thanks,
Pankaj
Try to work in this direction: https://stackoverflow.com/questions/15250928/how-to-change-springs-scheduled-fixeddelay-at-runtime
Thanks Lokesh , will try out this.
I am facing sudden stop in execution of scheduled task and there are no exception no log even in server.
can any body please suggest me what to do…..
That’s strange. Try putting whole code in scheduler inside try-catch. Catch Exception class in catch block. Set logging level debug.
Anybody, any idea??
Hi,
I am planning to write a web-app to create appointments with teachers. Student should be able to create an appointment with teacher at a time. How can we do this using Spring.
Hi,
I referred to your Spring MVC blog and it was very useful to me. I am planning to write an application using java to schedule appointment with teachers. Students can fix appointment with teachers by specifying the time. Student can fix one slot with one teacher at a time. Once the time is fixed, the application should not allow the student or the teacher to book the slot to others.
How can I use the Spring scheduler to achieve this? Also can Spring take date and time values to set up an appointment? Please let me know how to do this in spring.
Regards,
Pradeep
Why you need Spring scheduler for this. Schedulers are for executing a repeating task in certain interval. You just need to store appointment details in database using simple MVC and validate against it in other places.
Am i missing anything?
But If I store the appointment details in the DB, I need to do a lot of validation so that the student cannot crete another appointment with someone at the same time, the teacher cannot have appointment with other student at the same time.. etc. Is there any better way to do this?
Why lots of validations? You can reduce lots of logic by creating well-thought SELECT queries and unique key constraints.
Got it!! having a many to many relationship by having a join table ad putting the constraints I can get there. Cool.
Any idea of how to do a UI for the same. Like integrating the server with outlook or gmail or custom Calendar UI. PLease let me know.
Sorry on this. Never worked on something like this.
Its a great article….to the point!
Thanks for sharing