Friday, May 20, 2022

Spring Job Scheduling Using TaskScheduler And @Scheduled Annotation

In this post we’ll see job scheduling in Spring using TaskScheduler along with @EnableScheduling and @Scheduled annotations.


Spring TaskScheduler interface

Spring 3.0 introduced a TaskScheduler interface with a variety of methods for scheduling tasks to run at some point in the future.

public interface TaskScheduler {
 ScheduledFuture schedule(Runnable task, Trigger trigger);
 ScheduledFuture schedule(Runnable task, Date startTime);
 ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
 ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
 ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
 ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}

TaskScheduler implementations in Spring

  • TimerManagerTaskScheduler- when running within Application Server environments where threads should not be created directly by the application itself Spring provides a TimerManagerTaskScheduler that delegates to a CommonJ TimerManager instance, typically configured with a JNDI-lookup. Note that this implementation is deperecated as of 5.1, in favor of EE 7's DefaultManagedTaskScheduler.
  • ThreadPoolTaskScheduler- This implementation (default) can be used whenever external thread management is not a requirement. Internally, it delegates to a ScheduledExecutorService instance.

Spring Job Scheduling example using TaskScheduler

For configuring task scheduler using task namespace in XML configuration.

<?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:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/task
    http://www.springframework.org/task/spring-task.xsd">
    
    <context:component-scan base-package="org.netjs.service" />
    
    <task:annotation-driven scheduler="taskScheduler" />   
    <task:scheduler id="taskScheduler" pool-size="5" />
</beans>

In the configuration a task scheduler is configured with pool size of 5. Same configured scheduler is used to execute the methods annotated with @Scheduled annotation, <task:annotation-driven> element helps in detecting the methods annotated with @Scheduled annotation.

If you prefer Java configuration then you can use @EnableScheduling annotation to enable support for @Scheduled annotation. Also define a ThreadPoolTaskScheduler to be configured as a bean.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
@EnableScheduling
@ComponentScan(basePackages = "org.netjs.service")
public class AppConfig {
  @Bean
  public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    return threadPoolTaskScheduler;
  }
}

Method with @Scheduled annotation

import java.util.Date;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class TaskSchedulerDemoService {
 @Scheduled(fixedDelay=5000)
 public void methodWithFixedDelay() {
  System.out.println("Method scheduled to run after delay of 5 seconds - " + new Date());
 }
}

As you can see in the service class a method is scheduled to be executed every 5 seconds.

To run this Spring TaskScheduler and @Scheduled Annotation example you just need to load the XML configuration, method will be executed every 5 second by the container.

public class App {
  public static void main( String[] args ){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");

    context.registerShutdownHook();
  }
}

Use the following class for Java configuration-

public class App {
  public static void main( String[] args ){
    AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    context.registerShutdownHook();
  }
}

Output

Method scheduled to run after delay of 5 seconds - Tue Oct 30 11:29:59 IST 2018
Method scheduled to run after delay of 5 seconds - Tue Oct 30 11:30:04 IST 2018
Method scheduled to run after delay of 5 seconds - Tue Oct 30 11:30:09 IST 2018
Method scheduled to run after delay of 5 seconds - Tue Oct 30 11:30:14 IST 2018

Options with Spring @Scheduled Annotation

In the above example fixed delay property is used as trigger metadata for scheduling. There are other properties that can be used as trigger metadata for scheduling like fixed rate, initial delay, providing cron expression.

  • fixedDelay- With fixed delay the period will be measured from the completion time of last invocation. For example, if fixed delay is configured to be 5 seconds then next invocation = completion of last invocation + 5 seconds.
  • fixedRate- With fixed rate the period will be measured from the start times of each invocation. For example, if fixed rate is configured to be 5 seconds then next invocation = start of last invocation + 5 seconds.
    @Scheduled(fixedRate=5000)
    public void methodWithFixedRate() {
     System.out.println("Method scheduled to run every 5 seconds - " + new Date());
    }
    
  • initialDelay- 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 methodWithFixedRate() {
     System.out.println("Method scheduled to run every 5 seconds - " + new Date());
    }
    
  • cron- You can also provide a cron expression for scheduling. For example following method will be executed every 20 seconds starting at 11:45 AM and ending at 11:50 AM, every day.
    @Service
    public class TaskSchedulerDemoService {
     @Scheduled(cron="0/20 45-50 11 * * ?")
     public void methodWithFixedDelay() {
      System.out.println("Method scheduled to run every 20 seconds - " + new Date());
     }
    }
    

Restrictions with Spring @Scheduled annotation

  • The methods to be scheduled must have void returns.
  • Methods also should not have any arguments.
  • If the method needs to interact with other objects from the Application Context, then those would typically have been provided through dependency injection.

That's all for this topic Spring Job Scheduling Using TaskScheduler and @Scheduled Annotation. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Asynchronous Method Execution Support Using @Async Annotation
  2. Spring Email Scheduling Example Using Quartz Scheduler
  3. Spring MVC Checkbox And Checkboxes Form Tag Example
  4. Connection Pooling With Apache DBCP Spring Example
  5. Spring Batch Processing Using JDBCTemplate batchUpdate() Method

You may also like-

  1. BeanFactoryPostProcessor in Spring Framework
  2. ServiceLocatorFactoryBean in Spring
  3. Transaction Management in Spring
  4. Difference Between component-scan And annotation-config in Spring
  5. Garbage Collection in Java
  6. Reflection in Java - Getting Constructor Information
  7. Array in Java
  8. Java Collections Interview Questions And Answers

No comments:

Post a Comment