Monday, May 25, 2015

Spring Scheduler hello world example - run task in the future

Spring framework now support scheduler, so for most usage there is no need to involve other library, such as Quartz to do this.  The usage is very simple: add annotation @Scheduled(...) to any bean's method that need to be run in the future. The Spring context will create a thread to run it at the right time you specified in the future.

0. What you need

  • JDK 1.7
  • Maven 3.2.1
  • Spring 4.1.0.RELEASE

1. Configure the 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>
<modelversion>4.0.0</modelversion>
<groupid>com.shengwang.demo</groupid>
<artifactid>spring-scheduler-hello-world</artifactid>
<version>0.0.1-SNAPSHOT</version>

<dependencies>

<!-- Spring Context aritifact-->
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-context</artifactid>
<version>4.1.0.RELEASE</version>
</dependency>

</dependencies>

<!-- Using JDK 1.7 for compiling -->
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>


2. Define the Java Class



In the example there are 2 classes. The first one is a simple spring bean, but with annotation @Scheduled for method.

package com.shengwang.demo;

import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class Task {
/*
* The method will run on 13:40:00 everyday.
* cron format: sec min hour day mon week
*/
@Scheduled(cron="0 40 13 * * *")
public void runTask() {
System.out.println("Runing at " + new Date());
}
}


The second class is the main class.

package com.shengwang.demo;

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

public class DemoMain {

public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("app-context.xml");
}
}
The only line in the main is used to create the spring application context. If you run the main function, the program will not never finish since the spring context is not closed. so it will wait for the scheduled task to run in the future. The app-context.xml is the spring configuration file.

 



3. Spring configuration



The spring configuration file is named "app-context.xml" here. It stays in the main resources path /src/main/resources.

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

<!-- enable scheduling annotations -->
<task:annotation-driven scheduler="scheduler"/>
<task:scheduler id="scheduler" pool-size="15"/>

<!-- register spring beans -->
<context:component-scan base-package="com.shengwang.demo" />

</beans>


There are 2 lines start with <task:... /> used to configure spring scheduling. One thing need to mention is that (from spring official document):  If you do not provide a pool-size attribute, the default thread pool will only have a single thread. So in real practical, the pool-size is should always be set  to a number bigger than one to prevent any long task delaying all other scheduled tasks.

6 comments:

  1. Let assume i schedule a job for a minute , My first process started but not completed in a minute. at this moment second schedular task starting no matter if first scheduled task completed or not. how can we resolve it?

    ReplyDelete
    Replies
    1. @Scheduled can have fixDelay and fixRate properties. fixRate count from job start, fixDelay count from job finish. So if you don't want 2 same job running at the same time, just use fixDelay.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. How can I do if there is a job doesn't executed for some reason ?

    ReplyDelete
  5. Hi is possible run a @Scheduled method when running a web application?
    I want to create a web app build with Angular and Spring Data Rest - Mongodb by wich I can create some job that I want a scheduler inside the application every night will perform. How I can do that? I try to put @EnableScheduling in the main of my Spring Boot application but nothing happen

    ReplyDelete

Powered by Blogger.

About The Author

My Photo

Has been a senior software developer, project manager for 10+ years. Dedicate himself to Alcatel-Lucent and China Telecom for delivering software solutions.

Pages

Unordered List