原理不做介紹了,可以看這位大神的:https://www.cnblogs.com/zhangchengzhangtuo/p/5705672.html
1、maven(sql用作quatz的web操作持久化)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2、quatz核心代碼(只放核心代碼,具體代碼最後有地址鏈接)
①quatz配置
package com.quartz.config;
import org.mybatis.spring.annotation.MapperScan;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;
/**
* @description: Scheduler配置類
* @author: zyj
* @create: 2020-01-02 10:20
**/
@Configuration
@MapperScan({"com.quartz.**.dao"})
public class SchedulerConfig {
@Bean(name="SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//在quartz.properties中的屬性被讀取並注入後再初始化對象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/**
* quartz初始化監聽器
* 這個監聽器可以監聽到工程的啓動,在工程停止再啓動時可以讓已有的定時任務繼續進行。
* @return
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/**
*
*通過SchedulerFactoryBean獲取Scheduler的實例
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
②quatz執行類
package com.quartz.util;
import com.quartz.dao.QuartzDao;
import com.quartz.entity.AppQuartz;
import com.quartz.entity.JobAndTrigger;
import com.quartz.service.BaseJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.List;
import static org.quartz.DateBuilder.futureDate;
/**
* @description:
* @author: zyj
* @create: 2020-01-03 09:49
**/
@Component
public class QuartzUtil {
Logger logger = LoggerFactory.getLogger(QuartzUtil.class);
@Autowired
private QuartzDao quartzDao;
@Autowired
private DateUnit dateUnit;
//加入Qulifier註解,通過名稱注入bean
@Autowired
@Qualifier("Scheduler")
private Scheduler scheduler;
public List<JobAndTrigger> jobList(){
try {
return quartzDao.jobAndTriggerList();
}catch (Exception e){
logger.error("查詢定時任務列表失敗", e);
}
return null;
}
/**
* @Description: 新建一個任務
* @Param: [appQuartz]
* @return: java.lang.String
* @Author: zyj
* @Date: 2020/1/3
*/
public String addJob(AppQuartz appQuartz) throws Exception {
if ("".equals(appQuartz.getJobGroup()) || "".equals(appQuartz.getJobName()) || "".equals(appQuartz.getJobClassName()) || "".equals(appQuartz.getCronExpression())) {
return "沒有接收到參數,請檢查";
}
if (appQuartz.getTimeType() == null) {
return addCronJob(appQuartz);
}
return addSimpleJob(appQuartz);
}
/**
* @Description: 有參數job
* @Param: [appQuartz]
* @return: java.lang.String
* @Author: zyj
* @Date: 2020/1/3
*/
public String addCronJob(AppQuartz appQuartz) throws Exception {
// 啓動調度器
scheduler.start();
String className = appQuartz.getJobClassName().trim();
String [] classNames = className.split("\\.");
//構建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass())
.withDescription(appQuartz.getDesciption())
.withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup())
.build();
//表達式調度構建器(即任務執行的時間)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartz.getCronExpression());
//按新的cronExpression表達式構建一個新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger()
.withDescription(appQuartz.getDesciption())
.withIdentity(classNames[classNames.length-1], classNames[classNames.length-2])
.withSchedule(scheduleBuilder)
.build();
//傳遞參數
if(appQuartz.getInvokeParam()!=null && !"".equals(appQuartz.getInvokeParam())) {
trigger.getJobDataMap().put("invokeParam",appQuartz.getInvokeParam());
}
try {
scheduler.scheduleJob(jobDetail, trigger);
return "success";
} catch (SchedulerException e) {
logger.error("創建定時任務失敗", e);
return e.getMessage();
}
}
/**
* @Description: 暫停job
* @Param: [jobName 任務名, jobGroupName 任務組]
* @return: void
* @Author: zyj
* @Date: 2020/1/3
*/
public void jobPause(String jobName, String jobGroupName) throws Exception {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* @Description: 恢復任務
* @Param: [jobName 任務名, jobGroupName 任務組]
* @return: void
* @Author: zyj
* @Date: 2020/1/3
*/
public void jobResume(String jobName, String jobGroupName) throws SchedulerException {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* @Description: 刪除定時任務
* @Param: [jobName 任務名稱, jobGroupName任務組]
* @return: void
* @Author: zyj
* @Date: 2020/1/3
*/
public void jobDelete(String jobName, String jobGroupName) throws Exception {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
}
/**
* @Description: 修改任務
* @Param: [appQuartz]
* @return: java.lang.String
* @Author: zyj
* @Date: 2020/1/3
*/
public void modifyJob(AppQuartz appQuartz) throws Exception {
jobreschedule(appQuartz.getTriggerName(), appQuartz.getTriggerGroup(), appQuartz.getCronExpression());
}
/**
* @Description: 根據tigger修改任務
* @Param: [jobName, jobGroupName, cronExpression]
* @return: void
* @Author: zyj
* @Date: 2020/1/14
*/
public void jobreschedule(String triggerName, String triggerGroup, String cronExpression) throws Exception {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
// 表達式調度構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表達式重新構建trigger
CronTrigger triggerNew = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新設置job執行
scheduler.rescheduleJob(triggerKey, triggerNew);
}
/**
* @Description: 轉化爲time格式的定時任務
* @Param: [appQuartz]
* @return: java.lang.String
* @Author: zyj
* @Date: 2020/1/14
*/
public String addSimpleJob(AppQuartz appQuartz) throws Exception {
// 啓動調度器
scheduler.start();
String className = appQuartz.getJobClassName().trim();
String [] classNames = className.split("\\.");
//構建job信息
JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass())
.withDescription(appQuartz.getDesciption())
.withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup())
.build();
DateBuilder.IntervalUnit verDate = dateUnit.verification(appQuartz.getTimeType());
SimpleTrigger simpleTrigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withDescription(appQuartz.getDesciption())
.withIdentity(classNames[classNames.length-1], classNames[classNames.length-2])
.startAt(futureDate(Integer.parseInt(appQuartz.getCronExpression()), verDate))
.forJob(appQuartz.getJobClassName(), appQuartz.getJobGroup())
.build();
//傳遞參數
if(appQuartz.getInvokeParam()!=null && !"".equals(appQuartz.getInvokeParam())) {
simpleTrigger.getJobDataMap().put("invokeParam",appQuartz.getInvokeParam());
}
try {
scheduler.scheduleJob(jobDetail, simpleTrigger);
return "success";
} catch (SchedulerException e) {
logger.error("創建定時任務失敗", e);
return e.getMessage();
}
}
/**
* 根據類名稱,通過反射得到該類,然後創建一個BaseJob的實例。
* 由於自己的Job類都實現了BaseJob,
* 所以這裏不需要我們手動去判斷。這裏涉及到了一些java多態調用的機制
*
* @param classname
* @return
* @throws Exception
*/
public static BaseJob getClass(String classname) throws Exception {
Class<?> class1 = Class.forName(classname);
return (BaseJob) class1.newInstance();
}
}