spring boot + quartz定時任務框架入坑指南
阿新 • • 發佈:2019-01-23
quartz
Quartz是一個功能豐富的開源作業排程庫,可以整合到幾乎任何Java應用程式中
新增Maven依賴
<!-- druid阿里巴巴資料庫連線池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.3</version>
</dependency >
<!-- 資料庫操作隨便你用什麼 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId >com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.4</version>
</dependency>
<!-- quartz依賴 -->
<dependency>
<groupId>org.springframework</groupId >
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
構建基本類
定時任務通用介面
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public interface BaseJob extends Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException;
}
定時任務介面的實現類
import com.quartz.springquartz.task.BaseJob;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import java.time.LocalDateTime;
public class TestJob implements BaseJob {
public TestJob() {
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobKey key = jobDetail.getKey();
System.out.println(key.getName()+"-"+key.getGroup()+"執行時間: " + LocalDateTime.now().toString());
}
}
quartz的JAVA config bean注入
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import org.quartz.*;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
@Bean(name="SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
/*
* quartz初始化監聽器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/*
* 通過SchedulerFactoryBean獲取Scheduler的例項
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
/**
* 設定quartz屬性,可以從properties配置中讀取
*/
public Properties quartzProperties() throws IOException {
Properties prop = new Properties();
prop.put("quartz.scheduler.instanceName", "ServerScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
prop.put("org.quartz.scheduler.instanceId", "NON_CLUSTERED");
prop.put("org.quartz.scheduler.jobFactory.class", "org.quartz.simpl.SimpleJobFactory");
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "5");
return prop;
}
}
操作定時任務的service類,就不寫介面了直接實現,資料庫dao和service自己實現,Task是我定義的pojo
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.manager.TaskService;
import com.quartz.springquartz.task.BaseJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class ScheduleJobService {
@Autowired @Qualifier("Scheduler")
private Scheduler scheduler;
//自己選擇所用的dao
@Autowired
TaskService taskService;
public String addJob(Task task) throws Exception{
// 啟動排程器
scheduler.start();
//構建job資訊
JobDetail jobDetail = JobBuilder
.newJob(getClass(task.getClassName()).getClass()).withIdentity(task.getName(), task.getGroup()).build();
//表示式排程構建器(即任務執行的時間)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCron());
//按新的cronExpression表示式構建一個新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getName(), task.getGroup())
.withSchedule(scheduleBuilder).build();
try {
scheduler.scheduleJob(jobDetail, trigger);
//taskService.insert(task);
} catch (SchedulerException e) {
e.printStackTrace();
}
return "success";
}
public JobDetail jobPause(String jobName, String jobGroupName) throws Exception
{
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
JobDetail detail = scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
return detail;
}
public void jobreschedule(String jobName, String jobGroupName, String cronExpression) throws Exception
{
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
// 表示式排程構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表示式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新設定job執行
scheduler.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
System.out.println("更新定時任務失敗"+e);
}
}
public static BaseJob getClass(String classname) throws Exception
{
Class<?> class1 = Class.forName(classname);
return (BaseJob)class1.newInstance();
}
}
新增監聽器,應用啟動時,從資料庫中讀取定時任務並加入
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.manager.TaskService;
import com.quartz.springquartz.service.ScheduleJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
import java.util.List;
@Configuration
public class JobListener implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
TaskService taskService;
@Autowired
ScheduleJobService scheduleJobService;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent){
EntityWrapper<Task> ew = new EntityWrapper<>();
ew.where("status = {0}",1);
List<Task> tasks = taskService.selectList(ew);
System.out.println("task size = "+tasks.size());
try {
for (Task task : tasks) {
scheduleJobService.addJob(task);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
再寫一個controller測試用,就可以玩去了
import com.quartz.springquartz.entity.Task;
import com.quartz.springquartz.service.ScheduleJobService;
import com.quartz.springquartz.task.BaseJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping(value="/job")
public class TestController {
//加入Qulifier註解,通過名稱注入bean
@Autowired @Qualifier("Scheduler")
private Scheduler scheduler;
@Autowired
ScheduleJobService scheduleJobService;
@RequestMapping("/add")
public String addJob(@RequestBody Task task) throws Exception{
scheduleJobService.addJob(task);
return "success";
}
@PostMapping(value="/pause")
public JobKey pausejob(@RequestBody Map map) throws Exception
{
JobDetail detail = scheduleJobService.jobPause((String)map.get("jobName"), (String)map.get("jobGroupName"));
return detail.getKey();
}
@PostMapping(value="/edit")
public String rescheduleJob(@RequestBody Map map) throws Exception
{
scheduleJobService.jobreschedule((String)map.get("jobName"),(String)map.get("jobGroupName"),(String)map.get("cronExpression"));
return "success";
}
}
總結
最初入門,quartz配置中的儲存,分散式應用暫時沒看,下篇文章再說,只實現了單機中定時任務的資料庫持久化和動態新增