Java Articles

Advertisement

Spring Configuring TaskScheduler Examples

by Ram Satish

Share

A trigger determines the next execution time of a task. Triggers are based on fixed delay, fixed rating or cron expression. When a task is scheduled it can be based on on of these triggers or a custom implementation of Trigger interface. Spring abstracts the scheduling of a task using TaskScheduler interface.

In this article, we will see several ways of injecting TaskScheuler implementation. If none is set then the default implementation that gets configured is ThreadPoolTaskScheduler which in turn delegates to a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically.

Configuring TaskScheduler using a bean

By default spring delegates the task scheduling to ScheduledThreadPoolExecutor implementation with pool size one. In this example we will override the default single sized thread pool executor with the a thread pool executor of size ten. We just need to include a bean of class ThreadPoolTaskScheduler. Method poolScheduler() is a @Bean annotated method that returns an instance of ThreadPoolTaskScheduler. The pool size is set to ten and we also have given a name to the scheduler.

The class is annotated with @EnableScheduling so that the spring scheduler is configured. We also have a @Scheduled annotated method that is configured to run every two seconds.

Advertisement

SpringTaskScheduleBeanExample:

package com.javarticles.spring;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
@EnableScheduling
public class SpringTaskScheduleBeanExample {

private AtomicInteger counter = new AtomicInteger(0);

@Scheduled(fixedRate = 2000)
public void fixedRateJob() {
int jobId = counter.incrementAndGet();
System.out.println("Job @ fixed rate " + new Date() + ", jobId: " + jobId);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Job " + jobId + " done");
}

@Bean
public TaskScheduler poolScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("poolScheduler");
scheduler.setPoolSize(10);
return scheduler;
}

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringTaskScheduleBeanExample.class);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
context.close();
}
}
}

You can see from the output poolScheduler is started. Next the scheduler runs the task configured and in the end shuts down the scheduler.

Output:

May 16, 2016 5:19:43 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@49097b5d: startup date [Mon May 16 17:19:43 IST 2016]; root of context hierarchy
May 16, 2016 5:19:43 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler initialize
INFO: Initializing ExecutorService 'poolScheduler'
Job @ fixed rate Mon May 16 17:19:43 IST 2016, jobId: 1
Job 1 done
Job @ fixed rate Mon May 16 17:19:45 IST 2016, jobId: 2
Job 2 done
Job @ fixed rate Mon May 16 17:19:47 IST 2016, jobId: 3
May 16, 2016 5:19:48 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@49097b5d: startup date [Mon May 16 17:19:43 IST 2016]; root of context hierarchy
Job 3 done
May 16, 2016 5:19:48 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler shutdown
INFO: Shutting down ExecutorService 'poolScheduler'

Configuring TaskScheduler using SchedulingConfigurer

Another way of injecting TaskScheduler bean is by making a @Configuration annotated class implement SchedulingConfigurer interface. This gives a more programmatic control for setting a specific TaskSchedule bean. One can also configure custom triggers. See method configureTasks() where we not only set a scheduler but also add a new trigger.

SpringSchedulingConfigurerBeanExample:

package com.javarticles.spring;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.IntervalTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
@EnableScheduling
public class SpringSchedulingConfigurerBeanExample {

private AtomicInteger counter = new AtomicInteger(0);

@Scheduled(fixedRate = 2000)
public void fixedRateJob() {
int jobId = counter.incrementAndGet();
System.out.println("Job @ fixed rate " + new Date() + ", jobId: " + jobId);
}

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
SpringSchedulingConfigurerBeanExample.class);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
context.close();
}
}

@Configuration
static class RegisterTaskSchedulerViaSchedulingConfigurer implements SchedulingConfigurer {

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(poolScheduler());

taskRegistrar.addFixedRateTask(new IntervalTask(
new Runnable() {
@Override
public void run() {
System.out.println("Job @ fixed rate " + new Date() + ", Thread name is " + Thread.currentThread().getName());
}
},
1000, 0));
}

@Bean
public TaskScheduler poolScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setThreadNamePrefix("poolScheduler");
scheduler.setPoolSize(10);
return scheduler;
}
}
}

Output:

May 16, 2016 5:37:35 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4783da3f: startup date [Mon May 16 17:37:35 IST 2016]; root of context hierarchy
May 16, 2016 5:37:35 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler initialize
INFO: Initializing ExecutorService 'poolScheduler'
Job @ fixed rate Mon May 16 17:37:35 IST 2016, jobId: 1
Job @ fixed rate Mon May 16 17:37:35 IST 2016, Thread name is poolScheduler2
Job @ fixed rate Mon May 16 17:37:36 IST 2016, Thread name is poolScheduler1
Job @ fixed rate Mon May 16 17:37:37 IST 2016, Thread name is poolScheduler3
Job @ fixed rate Mon May 16 17:37:37 IST 2016, jobId: 2
Job @ fixed rate Mon May 16 17:37:38 IST 2016, Thread name is poolScheduler4
Job @ fixed rate Mon May 16 17:37:39 IST 2016, jobId: 3
Job @ fixed rate Mon May 16 17:37:39 IST 2016, Thread name is poolScheduler5
May 16, 2016 5:37:40 PM org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@4783da3f: startup date [Mon May 16 17:37:35 IST 2016]; root of context hierarchy
May 16, 2016 5:37:40 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler shutdown
INFO: Shutting down ExecutorService 'poolScheduler'

Configuring scheduler via XML

In our last example, we use task namespace based XML tags to configure a scheduler. <task:annotation-driven/> will configure the task scheduler bean processor. We can create a task scheduler bean and specify the task scheduler bean name in attribute scheduler.

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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">

<task:annotation-driven scheduler="poolScheduler"/>
<task:scheduler id="poolScheduler" pool-size="10"/>
<bean class="com.javarticles.spring.SpringTaskScheduleViaXMLExample" />
</beans>

SpringTaskScheduleViaXMLExample:

package com.javarticles.spring;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;

public class SpringTaskScheduleViaXMLExample {

private AtomicInteger counter = new AtomicInteger(0);

@Scheduled(fixedRate = 2000)
public void fixedRateJob() {
int jobId = counter.incrementAndGet();
System.out.println("Job @ fixed rate " + new Date() + ", jobId: " + jobId);
}

public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
context.close();
}
}
}

Output:

May 16, 2016 5:48:05 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Mon May 16 17:48:05 IST 2016]; root of context hierarchy
May 16, 2016 5:48:05 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
May 16, 2016 5:48:05 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler initialize
INFO: Initializing ExecutorService 'poolScheduler'
May 16, 2016 5:48:05 PM org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker postProcessAfterInitialization
INFO: Bean 'poolScheduler' of type [class org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler]is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Job @ fixed rate Mon May 16 17:48:05 IST 2016, jobId: 1
Job @ fixed rate Mon May 16 17:48:07 IST 2016, jobId: 2
Job @ fixed rate Mon May 16 17:48:09 IST 2016, jobId: 3
May 16, 2016 5:48:10 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Mon May 16 17:48:05 IST 2016]; root of context hierarchy
May 16, 2016 5:48:10 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler shutdown
INFO: Shutting down ExecutorService 'poolScheduler'

Download the source code

This was an example about the various ways of configuring spring task scheduler.

You can download the source code here: springTaskScheduerExample.zip

Share

Advertisement

Related

Advertisement

Latest

Advertisement