springboot 使用定時任務開發介紹
阿新 • • 發佈:2018-12-15
1 springboot 預設的定時任務處理
demo工具和版本說明:
jdk版本:1.8.0_144
springboot版本:2.0.5.RELEASE
使用spirngboot自帶的任務排程攏共需要2步
1 啟動類上宣告 @EnableScheduling
2 spring bean 方法上宣告 @Scheduled 並在註解中指定啟動的規則
直接上程式碼
package cn.lijunkui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class SpringbootlearnApplication { public static void main(String[] args) { SpringApplication.run(SpringbootlearnApplication.class, args); } }
package cn.lijunkui.task.own; 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; /** * http://www.bejson.com/othertools/cron/ * @author lijunkui * */ @Component public class SchedulerTask { private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); //固定的時間執行 也就是 5秒執行一次 @Scheduled(fixedRate = 5000) public void reportCurrentTimeFixedRate() { log.info("reportCurrentTimeFixedRate The time is now {}", dateFormat.format(new Date())); } }
測試效果
接下倆我們重點說一下 Scheduled 註解 的經常使用引數設定項
fixedRate :固定的時間執行 也就是 多少秒執行一次。 這個我們上面的程式碼已經介紹完畢。
fixedDelay:執行完畢後再過5秒後執行
initialDelay:啟動後延遲多少秒後執行 不能單獨使用。
接下倆看看fixedDelay 和 initialDelay 設定項的demo案例:
package cn.lijunkui; import java.text.SimpleDateFormat; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; import cn.lijunkui.task.own.SchedulerTask; @SpringBootApplication @EnableScheduling public class SpringbootlearnApplication { private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); public static void main(String[] args) { SpringApplication.run(SpringbootlearnApplication.class, args); log.info("reportCurrentTimeInitialDelay fixedRate The time is start {}", dateFormat.format(new Date())); } }
package cn.lijunkui.task.own;
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;
/**
* http://www.bejson.com/othertools/cron/
* @author jrrry
*
*/
@Component
public class SchedulerTask {
private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
//執行完畢後再過5秒後執行
@Scheduled(fixedRate= 5000)
public void reportCurrentTimeFixedDelay() {
log.info("reportCurrentTimeFixedDelay The time is now {}", dateFormat.format(new Date()));
}
//延遲1秒後執行 然後每5秒執行一次
@Scheduled(initialDelay=1000, fixedRate=5000)
public void reportCurrentTimeInitialDelay() {
log.info("reportCurrentTimeInitialDelay fixedRate The time is now {}", dateFormat.format(new Date()));
}
}
測試結果:
同時 Scheduled 還支援 Cron 表示式方式
package cn.lijunkui.task.own;
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 SchedulerTaskForCron {
private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
/**
* 每天的14:00 執行一次
*/
@Scheduled(cron="0 0 14 * * ?")
private void cron() {
log.info("cron The time is now {}", dateFormat.format(new Date()));
}
/**
* 每秒執行一次
*/
@Scheduled(cron="* * * * * ?")
private void cron2() {
log.info("cron2 The time is now {}", dateFormat.format(new Date()));
}
}
測試結果:
2 springboot 使用JDK 定時任務處理
2.1 Timer
package cn.lijunkui.task.jdk;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.lijunkui.task.own.SchedulerTask;
public class DemoTask extends TimerTask{
private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Override
public void run() {
log.info("DemoTask The time is now {}", dateFormat.format(new Date()));
}
}
package cn.lijunkui.task.jdk;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
public class TimerTest {
private DemoTask demoTask;
public TimerTest(DemoTask demoTask) {
this.demoTask = demoTask;
}
public void run() throws ParseException {
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
//timer.scheduleAtFixedRate(demoTask, delay, intevalPeriod);//每秒執行一次
//timer.scheduleAtFixedRate(demoTask, 1000, intevalPeriod);//延遲一秒後每秒執行一次
String datetimeStr = "2018-10-16 15:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date firstTime = sdf.parse(datetimeStr);
timer.schedule(demoTask, firstTime, intevalPeriod);//3點後開始執行 每秒執行一次
}
}
package cn.lijunkui.task.jdk;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(value = 1)
public class DemoTaskRunner implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
TimerTest test = new TimerTest(new DemoTask());
test.run();
}
}
2.2 ScheduledExecutorService
Java SE5 java.util.concurrent裡 ScheduledExecutorService 提供了新的任務排程的方式。他是採用執行緒池的方式來執行的,相對於 Timer 語法更為簡單。
package cn.lijunkui.task.jdk.scheduledExecutorService;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.lijunkui.task.own.SchedulerTask;
public class ScheduledExecutorTask implements Runnable{
private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Override
public void run() {
log.info("scheduledExecutorTask The time is now {}", dateFormat.format(new Date()));
}
}
package cn.lijunkui.task.jdk.scheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledExecutorTest {
private ScheduledExecutorTask task;
public ScheduledExecutorTest(ScheduledExecutorTask task) {
this.task = task;
}
public void run() {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
}
}
package cn.lijunkui.task.jdk.timer;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import cn.lijunkui.task.jdk.scheduledExecutorService.ScheduledExecutorTask;
import cn.lijunkui.task.jdk.scheduledExecutorService.ScheduledExecutorTest;
@Component
@Order(value = 1)
public class DemoTaskRunner implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
//TimerTest test = new TimerTest(new DemoTask());
//test.run();
ScheduledExecutorTest test = new ScheduledExecutorTest(new ScheduledExecutorTask());
test.run();
}
}
測試結果:
3 springboot 整合 quartz
springboot 2.0 已經有了quartz 的start依賴,我們可以直接引入quartz 的start依賴 來使用quartz 了。
首先我們先引入quartz start依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
定義quartz 的job
package cn.lijunkui.task.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MyJob extends QuartzJobBean{
@Autowired
private HelloService helloService;
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("hello,job name"+name+"age:"+age);
helloService.print();
}
}
建立quartz 的Config 同時定義 JobDetail 和 觸發器 Trigger
package cn.lijunkui.task.quartz;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyJobConfig {
@Bean
public JobDetail myJobDetail() {
return JobBuilder.newJob(MyJob.class).withIdentity("myJob").storeDurably()
.usingJobData("name","lijunkui")
.usingJobData("age",180)
.build();
}
@Bean
public Trigger myJobTrigger() {
//定義具體什麼執行時間. 設定一個每3秒執行一次的計劃表.
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever();
//定義觸發器.
return TriggerBuilder.newTrigger().forJob(myJobDetail()).withIdentity("myJobTrigger").withSchedule(simpleScheduleBuilder).build();
}
}
定義注入的Job的Service
package cn.lijunkui.task.quartz;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public void print(){
System.out.println("print");
}
}
測試日誌: