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;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.
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");
}
}
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.
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@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.
DeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHow can I do if there is a job doesn't executed for some reason ?
ReplyDeleteHi is possible run a @Scheduled method when running a web application?
ReplyDeleteI 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