解决问题:
不写入数据库;动态创建定时任务
1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2 配置文件
quartz:
job-store-type: jdbc
properties:
org:
quartz:
scheduler:
#调度器实例编号自动生成
instanceId: AUTO
jobStore:
#是否加入集群
isClustered: true
#调度实例失效的检查时间间隔
clusterCheckinInterval: 10000
# 在调度流程的第一步,也就是拉取待即将触发的triggers时,是上锁的状态,即不会同时存在多个线程拉取到相同的trigger的情况,也就避免的重复调度的危险
acquireTriggersWithinLock: true
3解释
查看一下 QuartzProperties 类
JobStoreType : 需要关注的 默认是 MEMORY 适应生产需要必须改为 JDBC 否则服务器一旦重启定时任务全部丢失
package org.springframework.boot.autoconfigure.quartz;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
/**
* Configuration properties for the Quartz Scheduler integration.
*
* @author Vedran Pavic
* @author Stephane Nicoll
* @since 2.0.0
*/
@ConfigurationProperties("spring.quartz")
public class QuartzProperties {
/**
* Quartz job store type.
*/
private JobStoreType jobStoreType = JobStoreType.MEMORY;
/**
* Name of the scheduler.
*/
private String schedulerName;
/**
* Whether to automatically start the scheduler after initialization.
*/
private boolean autoStartup = true;
/**
* Delay after which the scheduler is started once initialization completes. Setting
* this property makes sense if no jobs should be run before the entire application
* has started up.
*/
private Duration startupDelay = Duration.ofSeconds(0);
/**
* Whether to wait for running jobs to complete on shutdown.
*/
private boolean waitForJobsToCompleteOnShutdown = false;
/**
* Whether configured jobs should overwrite existing job definitions.
*/
private boolean overwriteExistingJobs = false;
/**
* Additional Quartz Scheduler properties.
*/
private final Map<String, String> properties = new HashMap<>();
private final Jdbc jdbc = new Jdbc();
public JobStoreType getJobStoreType() {
return this.jobStoreType;
}
public void setJobStoreType(JobStoreType jobStoreType) {
this.jobStoreType = jobStoreType;
}
public String getSchedulerName() {
return this.schedulerName;
}
public void setSchedulerName(String schedulerName) {
this.schedulerName = schedulerName;
}
public boolean isAutoStartup() {
return this.autoStartup;
}
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
public Duration getStartupDelay() {
return this.startupDelay;
}
public void setStartupDelay(Duration startupDelay) {
this.startupDelay = startupDelay;
}
public boolean isWaitForJobsToCompleteOnShutdown() {
return this.waitForJobsToCompleteOnShutdown;
}
public void setWaitForJobsToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
}
public boolean isOverwriteExistingJobs() {
return this.overwriteExistingJobs;
}
public void setOverwriteExistingJobs(boolean overwriteExistingJobs) {
this.overwriteExistingJobs = overwriteExistingJobs;
}
public Map<String, String> getProperties() {
return this.properties;
}
public Jdbc getJdbc() {
return this.jdbc;
}
public static class Jdbc {
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/quartz/impl/"
+ "jdbcjobstore/tables_@@platform@@.sql";
/**
* Path to the SQL file to use to initialize the database schema.
*/
private String schema = DEFAULT_SCHEMA_LOCATION;
/**
* Database schema initialization mode.
*/
private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED;
/**
* Prefixes for single-line comments in SQL initialization scripts.
*/
private List<String> commentPrefix = new ArrayList<>(Arrays.asList("#", "--"));
public String getSchema() {
return this.schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public DataSourceInitializationMode getInitializeSchema() {
return this.initializeSchema;
}
public void setInitializeSchema(DataSourceInitializationMode initializeSchema) {
this.initializeSchema = initializeSchema;
}
public List<String> getCommentPrefix() {
return this.commentPrefix;
}
public void setCommentPrefix(List<String> commentPrefix) {
this.commentPrefix = commentPrefix;
}
}
}
4 动态增加定时任务
JobDetail build = JobBuilder.newJob(ValidSourceSearchJob.class).withIdentity("Trigger_" + 123, "product-group").build();
// 构建参数
build.getJobDataMap().put("id", 123);
// 构建 Trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("Trigger_" + 123, "product-group").startAt(DateUtils.addDays(new Date(), days)).build();
try {
scheduler.scheduleJob(build, trigger);
scheduler.start();
logger.info("动态添加定时end:{}", .getId());
} catch (SchedulerException e) {
logger.error("添加定时任务异常:{}",.getId());
}
5 删除定时任务
@Autowired
private Scheduler scheduler;
//...
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
logger.info("删除定时任务完成:{}", jobName);
} catch (SchedulerException e) {
e.printStackTrace();
}
//...