注解方式
第一步、创建maven工程,引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
相关注解存在于spring-context-xxx.jar包中,依赖可以按需引入
第二步、创建调度任务
@Scheduled注解的方法不能有返回值,并且不能有形参
package hello;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}
第三步、SpringBoot方式启动容器、测试
在@Configuration注解的类上添加**@EnableScheduling**注解,为@Scheduled提供调度支持
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
}
或者在spring配置文件中加入以下代码来启用任务调度
<!-- 定时任务注解驱动 -->
<task:annotation-driven/>
注:@SpringBootApplication注解是非常便利偷懒的方式,它包含了@Configuration、@EnableAutoConfiguration、 @EnableWebMvc、@ComponentScan的功能
运行结果:
2016-08-26 16:23:06.316 INFO 37376 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 16:23:06
2016-08-26 16:23:11.316 INFO 37376 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 16:23:11
2016-08-26 16:23:16.316 INFO 37376 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 16:23:16
@Scheduled Annotation
fixdDelay:以指定时间间隔调度(以方法执行结束时间为准)
@Scheduled(fixedDelay=5000)public void doSomething() {
// something that should execute periodically
}
fixedRate:以指定时间间隔调度任务(以方法执行开始时间为准)
@Scheduled(fixedRate=5000)public void doSomething() {
// something that should execute periodically
}
initialDelay:指定延迟后开始调度任务
@Scheduled(initialDelay=1000, fixedRate=5000)public void doSomething() {
// something that should execute periodically
}
cron表达式: 如下表示只在工作日每5秒执行一次
@Scheduled(cron="*/5 * * * * MON-FRI")public void doSomething() {
// something that should execute on weekdays only
}
fixdDelay和fixedRate的区别通过下面代码便能理解
fixedRate:
@Scheduled(fixedRate = 3000)
public void reportCurrentTime() throws InterruptedException {
log.info("Sleep a while");
Thread.sleep(2000l);
log.info("The time is now {}", dateFormat.format(new Date()));
}
运行结果:
016-08-26 17:06:30.589 INFO 24844 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:06:30
2016-08-26 17:06:31.589 INFO 24844 — [pool-1-thread-1] hello.ScheduledTasks : Sleep a while
2016-08-26 17:06:33.589 INFO 24844 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:06:33
2016-08-26 17:06:34.589 INFO 24844 — [pool-1-thread-1] hello.ScheduledTasks : Sleep a while
2016-08-26 17:06:36.590 INFO 24844 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:06:36
fixdDelay:
@Scheduled(fixedDelay = 3000)
public void reportCurrentTime() throws InterruptedException {
log.info("Sleep a while");
Thread.sleep(2000l);
log.info("The time is now {}", dateFormat.format(new Date()));
}
运行结果:
2016-08-26 17:08:24.959 INFO 9996 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:08:24
2016-08-26 17:08:27.963 INFO 9996 — [pool-1-thread-1] hello.ScheduledTasks : Sleep a while
2016-08-26 17:08:29.964 INFO 9996 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:08:29
2016-08-26 17:08:32.964 INFO 9996 — [pool-1-thread-1] hello.ScheduledTasks : Sleep a while
2016-08-26 17:08:34.964 INFO 9996 — [pool-1-thread-1] hello.ScheduledTasks : The time is now 17:08:34
XML方式
第一步、创建调度任务
package hello;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component("scheduledTasks2")
public class ScheduledTasks2 {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks2.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
public void reportCurrentTime() throws InterruptedException {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}
第二步、xml配置
创建任务调度配置文件spring-task.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"
xmlns:context="http://www.springframework.org/schema/context"
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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描已经注册的bean-->
<context:component-scan base-package="hello">
</context:component-scan>
<!--创建指定线程池大小的ThreadPoolTaskScheduler实例-->
<task:scheduler id="myScheduler" pool-size="5"/>
<!--调度任务列表-->
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="scheduledTasks2" method="reportCurrentTime" fixed-delay="5000" initial-delay="1000"/>
<!-- <task:scheduled ref="beanB" method="methodB" fixed-rate="5000"/>
<task:scheduled ref="beanC" method="methodC" cron="*/5 * * * * MON-FRI"/>-->
</task:scheduled-tasks>
</beans>
第三步、SpringBoot方式启动容器、测试
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource(locations={"classpath:spring-task.xml"})
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
}
运行结果:
2016-08-29 11:47:11.615 INFO 26656 — [ myScheduler-1] hello.ScheduledTasks2 : The time is now 11:47:11
2016-08-29 11:47:16.621 INFO 26656 — [ myScheduler-1] hello.ScheduledTasks2 : The time is now 11:47:16
2016-08-29 11:47:21.622 INFO 26656 — [ myScheduler-2] hello.ScheduledTasks2 : The time is now 11:47:21
注:xml配置文件中
<context:component-scan base-package="hello">
</context:component-scan>
其实多余了,因为SpringBootApplication已经包含bean扫描的功能
参考
http://spring.io/guides/gs/scheduling-tasks/
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html