Spring @Scheduled – 4 Ways to Schedule Tasks

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 –

  1. fixedRate makes Spring run the task on periodic intervals even if the last invocation may be still running.
  2. fixedDelay specifically controls the next execution time when the last execution finishes.
  3. 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 –

  1. Using @Scheduled annotation would in turn make Spring container understand that the method underneath this annotation would run as a job.
  2. Remember that the methods annotated with @Scheduled should not have parameters passed to them.
  3. They should not return any values too.
  4. 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

Was this post helpful?

Join 8000+ Awesome Developers, Like YOU!

73 thoughts on “Spring @Scheduled – 4 Ways to Schedule Tasks”

  1. 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.

    Reply
  2. 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 ?

    Reply
  3. 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…

    Reply
  4. Thanks Lokesh, great article.

    I am using @Scheduled in spring boot application, to send the new news after every 5minutes, find below code snippet:

    
    @Component
    public class NewsScheduler{
    
    	@Scheduled(cron = "0 0/5 * 1/1 * ?" , zone="Asia/Calcutta")
    	public synchronized void syncData() {
                     System.out.println("inside scheduled job ");
                     sendTodaysNews();
           }
    }
    
    

    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.

    Reply
  5. 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

    <?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 class="com.hemal.spring.SpringSchedulingEnabledViaXMLExample" />
    	
    </beans>
    

    My SpringSchedulerCronExample.java

    package com.hemal.spring;
    
    import java.util.Date;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    
    @Configuration
    @EnableScheduling
    public class SpringScheduleCronExample {
        private AtomicInteger counter = new AtomicInteger(0);
    
        @Scheduled(cron = "${cron.expression}")
        public void cronJob() {
            int jobId = counter.incrementAndGet();
            System.out.println("Job @ cron " + new Date() + ", jobId: " + jobId);
        }
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context 
            		= new AnnotationConfigApplicationContext(
                    			SpringScheduleCronExample.class);
            try {
                Thread.sleep(12000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                context.close();
            }
        }
    }
    

    And my application.properties are under src/main/resources

    cron.expression=*/5 * * * * ?

    Reply
  6. 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?

    Reply
  7. 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?

    Reply
  8. 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

    Reply
  9. 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?

    Reply
  10. 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?

    Reply
  11. 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.

    Reply
  12. 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.

    Reply
  13. 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

    Reply
    • The sourcecode of the project is attached in last of post. Please see the classes to to execute the examples in “test” package.

      package com.howtodoinjava.service;
      
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestDemoService {
      	public static void main(String[] args) {
      		new ClassPathXmlApplicationContext(&quot;schedule-basicUsageCron-example.xml&quot;);
      		new ClassPathXmlApplicationContext(&quot;schedule-basicUsageFixedDelay-example.xml&quot;);
      		new ClassPathXmlApplicationContext(&quot;schedule-xmlConfig-example.xml&quot;);
      		new ClassPathXmlApplicationContext(&quot;schedule-PropertiesConfig-example.xml&quot;);
      	}	
      }
      
      Reply
      • 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.

        Reply
  14. 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?

    Reply
      • 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!!

        Reply
  15. 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?

    Reply
  16. 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?

    Reply
  17. 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.

    Reply
  18. 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!

    Reply
  19. 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.

    Reply
  20. 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…..

    Reply
  21. 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.

    Reply
  22. 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

    Reply
    • 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?

      Reply
      • 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?

        Reply

Leave a Comment

About HowToDoInJava

This blog provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.