Categories: spring

Spring Job Scheduling using TaskScheduler (XML Config)

In this post we will see how to Schedule a job in Spring using Spring Task Scheduler with XML configuration. Annotation based configuration is explained in Annotation based scheduling configuration post. Let’s get going.


Following technologies being used:

  • Spring 4.0.6.RELEASE
  • Maven 3
  • JDK 1.6
  • Eclipse JUNO Service Release 2

Project directory structure:

Following will be the final project directory structure for this example:

Let’s now add the content mentioned in above structure explaining each in detail.

Step 1: Provide Spring dependencies in Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.websystique.spring</groupId>
 <artifactId>SpringSchedulingXmlExample</artifactId>
 <version>1.0.0</version>
 <packaging>jar</packaging>
 <name>SpringSchedulingXmlExample</name>

 <properties>
  <springframework.version>4.0.6.RELEASE</springframework.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${springframework.version}</version>
  </dependency>
 </dependencies>
 <build>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>3.2</version>
     <configuration>
      <source>1.6</source>
      <target>1.6</target>
     </configuration>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

</project>

Step 2: Create Scheduler Task Bean

Scheduler Task bean is ordinary POJO bean whose method will be called via Scheduler.

package com.websystique.spring.scheduling;

import org.springframework.stereotype.Component;

@Component("myBean")
public class MyBean {

 public void printMessage() {
  System.out.println("I am called by Spring scheduler");
 }
}

Note that the method which will be called via scheduler (printMessage in this example) must return void and must not have any parameters. Of course you can inject another bean in above bean to get some external functionality called in printMessage.

Step 3: Configure Spring Scheduling

<?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-4.0.xsd
             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
             http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">


 <context:component-scan base-package="com.websystique.spring.scheduling" />

 <task:scheduled-tasks scheduler="myScheduler">
  <task:scheduled ref="myBean" method="printMessage" fixed-delay="5000" />
 </task:scheduled-tasks>

 <task:scheduler id="myScheduler"/>

</beans>

Let’s understand each configuration step in detail

Firstly we need to configure a scheduler itself which schedules some tasks to run at some point in the future.

<task:scheduler id="myScheduler"/>

Above configuration creates Scheduler with default thread pool having only single thread. In case you have tasks which can take long time to complete, and are frequent, you can configure thread-pool with specified pool-size to handle each tasks in separate thread.

 <task:scheduler id="myScheduler" pool-size="10"/>

Next, we configure the tasks to be scheduled.

 <task:scheduled-tasks scheduler="myScheduler">
  <task:scheduled ref="myBean" method="printMessage" fixed-delay="5000" />
 </task:scheduled-tasks>

task:scheduled defines a new task. Attribute ‘ref’ refers to the bean whose method (referred by attribute ‘method’) will be called on specific time condition. fixed-delay specifies the time in milliseconds between the completion of first task and start of next task.

Here we are saying that myBean.printMessage() will be by scheduler periodically, with 5 seconds delay between completion of first task and start of next task.

Periodicity of scheduler can be defined in other ways as well. For example:

 <task:scheduled-tasks scheduler="myScheduler">
  <task:scheduled ref="myBean" method="printMessage" fixed-delay="5000" initial-delay="1000"/>
  <task:scheduled ref="Bean2" method="method2" fixed-rate="5000" />
  <task:scheduled ref="Bean3" method="method3" cron="*/5 * * * * MON-FRI"/>
 </task:scheduled-tasks>

In above config, we have specified there scheduled tasks with different periodicity.

initial-delay parameter specifies the number of milliseconds to wait before the first execution of the method.
fixed-rate specifies the number of milliseconds between each method start , regardless of how long method takes to complete.
cron provides more fine-grained control on task execution. Here we have configured task3 to run every 5 seconds but only on weekdays.

Step 4: Create Main and Run it

package com.websystique.spring;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {

 public static void main(String args[]){
  AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");
 }
 
}

Note that we are not calling any explicit scheduling class or method here. As we have configured the context in app-config.xml, context will be loaded and scheduling will be setup.

Run above program as Java Application, you will see following output

Aug 23, 2014 4:52:27 PM org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler initialize
INFO: Initializing ExecutorService  'myScheduler'
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
I am called by Spring scheduler
...

You can see that method printMessage of Bean MyBean gets called periodically.

That’s it. In the next tutorial , we will see same example using Annotation based configuration.

Download Source Code


References

View Comments

  • I am trying to parameterize cron expression via a properties file. 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

    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 * * * * ?

Share
Published by

Recent Posts

Spring Boot + AngularJS + Spring Data + JPA CRUD App Example

In this post we will be developing a full-blown CRUD application using Spring Boot, AngularJS, Spring Data, JPA/Hibernate and MySQL,…

8 years ago

Spring Boot Rest API Example

Spring Boot complements Spring REST support by providing default dependencies/converters out of the box. Writing RESTful services in Spring Boot…

8 years ago

Spring Boot WAR deployment example

Being able to start the application as standalone jar is great, but sometimes it might not be possible to run…

8 years ago

Spring Boot Introduction + hello world example

Spring framework has taken the software development industry by storm. Dependency Injection, rock solid MVC framework, Transaction management, messaging support,…

8 years ago

Secure Spring REST API using OAuth2

Let's secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a…

8 years ago

AngularJS+Spring Security using Basic Authentication

This post shows how an AngularJS application can consume a REST API which is secured with Basic authentication using Spring…

8 years ago