1. 程式人生 > >springboot 使用定時任務開發介紹

springboot 使用定時任務開發介紹

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");
	 }
}

測試日誌: