当前位置:网站首页>[quartz] read configuration from database to realize dynamic timing task
[quartz] read configuration from database to realize dynamic timing task
2022-06-26 04:55:00 【Only empty city】
Preface
stay Java Medium timed tasks are common , Use @Scheduled Annotation can realize timing , However, in the production environment, you may encounter the self configuring timing time of the scheduled task on the page , Used alone in this case @Scheduled Annotations are hard to implement timed tasks , So we can store the scheduled tasks in the database and use quartz Realize dynamic timing task .
Configuration dependency
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
Realization way
1、 Scheduled task table entity
@Data
@TableName("SCHEDULE_JOB")
public class ScheduleJob {
/**
* Serial number
*/
@TableId(value = "ID", type = IdType.ID_WORKER_STR)
private String id;
/**
* The name of the task
*/
@TableField("JOB_NAME")
private String jobName;
/**
* Task groups
*/
@TableField("JOB_GROUP")
private String jobGroup;
/**
* Task status Whether to start the task ,2: invalid ;1: It works
*/
@TableField("JOB_STATUS")
private Integer jobStatus;
/**
* cron expression , Recommended 6 Domain
*/
@TableField("CRON_EXPRESSION")
private String cronExpression;
/**
* describe
*/
@TableField("DESCRIPTION")
private String description;
/**
* Which class of methods is called when the task is executed Package name + Class name , The full path
*/
@TableField("BEAN_CLASS")
private String beanClass;
/**
* Whether the task has status
*/
@TableField("IS_CONCURRENT")
private Integer isConcurrent;
/**
* spring bean The class name corresponding to the scheduled task , Initial lowercase
*/
@TableField("SPRING_ID")
private String springId;
/**
* The method name of the task call
*/
@TableField("method_name")
private String methodName;
@TableField("CREATE_TIME")
private Date createTime;
@TableField("UPDATE_TIME")
private Date updateTime;
}
2、 Reflection call scheduleJob The method defined in
import com.saas.reptile.common.result.Result;
import com.saas.reptile.entity.po.ScheduleJob;
import com.saas.reptile.utils.LogUtils;
import com.saas.reptile.utils.SpringUtils;
import com.saas.reptile.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import java.lang.reflect.Method;
public class TaskUtils {
@Autowired
private ApplicationContext applicationContext;
/**
* Call by reflection scheduleJob The method defined in
*
* @param scheduleJob
*/
public static void invokMethod(ScheduleJob scheduleJob) {
try {// Add maximum exception catches
String springId = scheduleJob.getSpringId();
Object object = null;
Class clazz = null;
// According to reflection
if (StringUtils.isNotBlank(springId)) {
object = SpringUtils.getBean(springId);
}
if (object == null && StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
String jobStr = " Timing task name = [" + scheduleJob.getJobName() + "]- stay spring There is no such springId, adopt class type Getting ...";
LogUtils.info(jobStr, scheduleJob.getBeanClass());
try {
clazz = Class.forName(scheduleJob.getBeanClass());
object = SpringUtils.getBean(clazz);
if(object == null){
jobStr = " Timing task name = [" + scheduleJob.getJobName() + "]- stay spring Did not get bean, call spring Method is being built again ...";
LogUtils.info(jobStr, scheduleJob.getBeanClass());
object = SpringUtils.getBeanByType(clazz);
}
if (StringUtils.isNotBlank(springId)) {
SpringUtils.setBean(springId, object);
LogUtils.info("spring bean The build is complete and added to the container ", scheduleJob.getBeanClass());
}
LogUtils.info(" Timing task spring bean Building a successful ! ", scheduleJob.getBeanClass());
} catch (Exception e) {
LogUtils.error(" Timing task spring bean The build failed !!! ", scheduleJob.getBeanClass(), e);
Result.fail(e);
return;
}
}
clazz = object.getClass();
Method method = null;
try {
method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
} catch (NoSuchMethodException e) {
String jobStr = " Timing task name = [" + scheduleJob.getJobName() + "] = Not started successfully , Method name setting error !!!";
LogUtils.error(jobStr, e);
} catch (SecurityException e) {
LogUtils.error("TaskUtils Something goes wrong ", e);
Result.fail(e);
}
if (method != null) {
try {
method.invoke(object);
LogUtils.info(" Timing task name = [" + scheduleJob.getJobName() + "] = Successful launch ");
} catch (Exception e) {
Result.fail(e);
LogUtils.error(" Timing task name = [" + scheduleJob.getJobName() + "] = Failed to start !!!", e);
return;
}
} else {
String jobStr = " Timing task name = [" + scheduleJob.getJobName() + "] = Failed to start !!!";
LogUtils.error(jobStr, clazz.getName(), "not find method ");
}
} catch (Exception e) {// Add maximum exception catches
Result.fail(e);
LogUtils.error(" Timing task name = [" + scheduleJob.getJobName() + "] = Failed to start !!!", e);
}
}
}
3、 Create... In normal state job Execution plant
import com.saas.reptile.entity.po.ScheduleJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class QuartzJobFactory implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
4、 If a method cannot be executed at one time, the next operation will not be executed until the modified method is executed at the next rotation
import com.saas.reptile.entity.po.ScheduleJob;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
5、 Create a scheduled task class that needs to be run
@Component
public class ClassAtmosphereTask {
public void work(){
// do something
}
}
6、SpringBean Factory tools
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements BeanFactoryPostProcessor {
// Spring Application context
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
/**
* Get objects
*
* @param name
* @return Object One registered under the given name bean Example
* @throws BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}
/**
* Get objects
* @return Object One registered under the given name bean Example
* @throws BeansException
*/
@SuppressWarnings("unchecked")
public static <T> T getBeanByType(Class<T> clzee) throws BeansException {
try {
return beanFactory.createBean(clzee);
} catch (NoSuchBeanDefinitionException e) {
return null;
}
}
/**
* Inject an object
* @return Object One registered under the given name bean Example
* @throws BeansException
*/
@SuppressWarnings("unchecked")
public static void setBean(String springId, Object obj) throws BeansException {
beanFactory.registerSingleton(springId, obj);
}
/**
* The acquisition type is requiredType The object of
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
try {
@SuppressWarnings("unchecked")
T result = (T) beanFactory.getBean(clz);
return result;
} catch (NoSuchBeanDefinitionException e) {
return null;
}
}
/**
* If BeanFactory Contains a... That matches the given name bean Definition , Then return to true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return beanFactory.containsBean(name);
}
/**
* Judge what is registered with a given name bean The definition is a singleton Or a prototype.
* If the given name corresponds to bean Definition not found , An exception will be thrown (NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class Type of registered object
* @throws NoSuchBeanDefinitionException
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}
/**
* If given bean Name in bean There are aliases in the definition , Then return these aliases
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getAliases(name);
}
}
7、 Other tools used
- String utility class
public class StringUtils {
public final static String REG_DIGIT = "[0-9]*";
public final static String REG_CHAR = "[a-zA-Z]*";
public final static String EMPTY = "";
/**
* Determine whether it is null
*/
public static boolean isEmpty(Object... obj) {
if(obj == null)
return true;
for(Object object : obj) {
if (object == null)
return true;
if (object.toString().trim().length() == 0)
return true;
}
return false;
}
public static boolean isBlankEmpty(Object obj) {
if (obj == null || "".equals(obj) || "".equals(obj.toString().trim()) || "null".equalsIgnoreCase(obj.toString()))
return true;
return false;
}
/**
* Is it empty , Or an empty string , Or for "null"
* @author guoyu
*/
public static boolean isBlankEmpty(Object... objs) {
if (objs == null || objs.length == 0)
return true;
for (Object obj : objs) {
if (isBlankEmpty(obj)) {
return true;
}
}
return false;
}
public static boolean isNotBlank(String pattern) {
return !isBlankEmpty(pattern);
}
public static boolean isBlank(String pattern) {
return isBlankEmpty(pattern);
}
public static String formatCountNames(String nameList) {
String[] names = nameList.split(",");
Map<String, Integer> nameCount = new HashMap<String, Integer>();
for(String name : names) {
if(StringUtils.isEmpty(name)) continue;
if(nameCount.containsKey(name)) {
Integer count = nameCount.get(name) + 1;
nameCount.put(name, count);
} else {
nameCount.put(name, 1);
}
}
StringBuilder newNames = new StringBuilder();
for(String key : nameCount.keySet()) {
if(StringUtils.isEmpty(key)) continue;
Integer count = nameCount.get(key);
String splitChar = newNames.length() > 0 ? "," : "";
newNames.append(splitChar).append(key).append("x").append(count);
}
return newNames.toString();
}
public static boolean isDigit(String str){
return isNumeric(str);
}
public static boolean isChar(String str){
return str.matches(REG_CHAR);
}
public static Boolean isNotEmpty(Object... obj) {
Boolean r = StringUtils.isEmpty(obj);
return !r;
}
public static boolean isNumeric(String str) {
if(isBlankEmpty(str)) return false;
for (int i = str.length(); --i >= 0;) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* string Medium str In the countdown num Position in
* @author guoyu
*/
public static int stringLastlndex(String string, String str, int num) {
int indexOf = string.lastIndexOf(str);
if(num > 1){
return stringLastlndex(string.substring(0, indexOf), str, num - 1);
} else {
return indexOf;
}
}
public static String getValue(Object val) {
return val == null ? "" : val.toString().replace("\n", "");
}
public static String getFileName(boolean type, Date startDate, String tableName){
String dateString = dateFormat(startDate,"yyyyMMdd");
StringBuffer stringBuffer = new StringBuffer(dateString);
stringBuffer.append("_");
stringBuffer.append(tableName);
stringBuffer.append("_");
if (type) {
stringBuffer.append("insert&");
} else {
stringBuffer.append("update&");
}
return stringBuffer.toString();
}
public static String getRefundNumber(Integer payRefundNum) {
if (payRefundNum == null) payRefundNum = 0;
payRefundNum = payRefundNum + 1;
String string = String.valueOf(payRefundNum);
if (string.length() == 1) {
return "0"+string;
}
return string;
}
private static String dateFormat(Date date, String datePattern) {
if(date == null) return "";
if(datePattern == null) datePattern = "yyyy-MM-dd";
SimpleDateFormat df = new SimpleDateFormat(datePattern, Locale.UK);
return df.format(date);
}
}
- Log tool class
import org.apache.commons.logging.LogFactory;
public class LogUtils {
private static final org.apache.commons.logging.Log logger;
private static final Object lock = new Object();
static {
synchronized (lock) {
logger = LogFactory.getLog(LogUtils.class);
}
}
public static void info(Object... msgs) {
StringBuilder stringBuilder = new StringBuilder();
Throwable e = null;
for (Object msg : msgs) {
if (msg != null) {
if (msg instanceof Throwable) {
e = (Throwable) msg;
} else {
stringBuilder.append(msg).append(" ");
}
}
}
logger.info(stringBuilder, e);
}
public static void error(Object... msgs) {
StringBuilder stringBuilder = new StringBuilder();
Throwable e = null;
for (Object msg : msgs) {
if (msg != null) {
if (msg instanceof Throwable) {
e = (Throwable) msg;
} else {
stringBuilder.append(msg).append(" ");
}
}
}
logger.error(stringBuilder, e);
}
public static void warn(Object... msgs) {
StringBuilder stringBuilder = new StringBuilder();
Throwable e = null;
for (Object msg : msgs) {
if (msg != null) {
if (msg instanceof Throwable) {
e = (Throwable) msg;
} else {
stringBuilder.append(msg).append(" ");
}
}
}
logger.warn(stringBuilder, e);
}
public static void debug(Object... msgs) {
StringBuilder stringBuilder = new StringBuilder();
Throwable e = null;
for (Object msg : msgs) {
if (msg != null) {
if (msg instanceof Throwable) {
e = (Throwable) msg;
} else {
stringBuilder.append(msg).append(" ");
}
}
}
logger.debug(stringBuilder, e);
}
}
- Data analysis constant class
public final class Constant {
private Constant() {
}
// Scheduled task running status : function
public static final Integer STATUS_RUNNING = 1;
// Scheduled task running status : stop it
public static final Integer STATUS_NOT_RUNNING = 2;
// Whether the scheduled task has status : Yes ( The default is 1, Abandoning )
public static final Integer CONCURRENT_IS = 1;
// Whether the scheduled task has status : nothing ( The default is 1, Abandoning )
public static final Integer CONCURRENT_NOT = 0;
}
- Interface return parameter class
@Data
public class Result<T> {
private Integer code;
private T data;
private String msg;
public Result() {
super();
}
public Result(T data) {
this.data = data;
}
public static Result success()
{
return success("");
}
public static <T> Result success(T data) {
Result<T> result = new Result<>(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getName());
result.setData(data);
return result;
}
public static <T> Result<T> fail(ResultEnum resultEnum) {
return createResult(null, resultEnum.getCode(), resultEnum.getName());
}
public static <T> Result<T> fail(Integer code, String message) {
return createResult(null, code, message);
}
public static <T> Result<T> fail(Throwable e) {
// Print the exception stack information to the console
e.printStackTrace();
return createResult(null, 500, " Server error ");
}
private static <T> Result<T> createResult(T data, Integer code, String message) {
Result<T> r = new Result<>();
r.setCode(code);
r.setData(data);
r.setMsg(message);
return r;
}
public Result(Integer code, String msg)
{
this.code = code;
this.msg = msg;
}
}
among ResultEnum The categories are as follows :
public enum ResultEnum {
SUCCESS(200," The request is successful "),
UN_KNOWN_ERROR(-1, " Unknown error "),
PARAM_NULL_ERROR(10001," The parameter is empty. "),
PERMISSION_ACCESS_DENIED(50001, "permission access denied");
private int code;
private String name;
private ResultEnum(int code, String name) {
this.code = code;
this.name = name;
}
public int getCode() {
return this.code;
}
public String getName() {
return this.name;
}
public static ResultEnum getNameByCode(int code) {
for (ResultEnum resultEnum : ResultEnum.values()) {
if (code == resultEnum.getCode()) {
return resultEnum;
}
}
return null;
}
}
8、sql sentence
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for schedule_job
-- ----------------------------
DROP TABLE IF EXISTS `schedule_job`;
CREATE TABLE `schedule_job` (
`id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT ' Primary key ',
`job_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' The name of the task ',
`job_group` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' Task groups ',
`job_status` int(0) DEFAULT NULL COMMENT ' Task status Whether to start the task ;1: It works ;2: invalid ',
`cron_expression` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'cron expression , Recommended 6 Domain ',
`description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' Timed task description ',
`bean_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' Which class of methods is called when the task is executed Package name + Class name , The full path ',
`is_concurrent` int(0) DEFAULT 1 COMMENT ' Whether the task has status ;0: No, ;1: Yes ',
`spring_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' Registered Bean, So keep consistent with the class name , Initial lowercase ',
`method_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT ' The method name of the task call ',
`create_time` datetime(0) DEFAULT NULL COMMENT ' Creation time ',
`update_time` datetime(0) DEFAULT NULL COMMENT ' Update time ',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of schedule_job
-- ----------------------------
INSERT INTO `schedule_job` VALUES ('1', 'ClassAtmosphereTask', 'ClassAtmosphereTask', 1, '0 30 23 * * ?', ' Class atmosphere value fixed task ', 'com.saas.reptile.task.ClassAtmosphereTask', 1, 'classAtmosphereTask', 'work', '2022-06-25 21:38:42', '2022-06-25 21:38:45');
SET FOREIGN_KEY_CHECKS = 1;
The notes are very detailed , among :
job_name and job_group Keep consistent ;
is_concurrent The default is 1;
The class of task execution should be full path and so on .
9、 Method realization
Written in service In the implementation class of
package com.saas.reptile.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.saas.reptile.common.quartz.QuartzJobFactory;
import com.saas.reptile.common.quartz.QuartzJobFactoryDisallowConcurrentExecution;
import com.saas.reptile.entity.po.ScheduleJob;
import com.saas.reptile.mapper.ScheduleJobMapper;
import com.saas.reptile.service.ScheduleJobService;
import com.saas.reptile.utils.Constant;
import com.saas.reptile.utils.LogUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Service
public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobMapper, ScheduleJob>
implements ScheduleJobService {
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
/**
* Add scheduled tasks to the database
* @param scheduleJob
*/
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addTask(ScheduleJob scheduleJob) {
this.baseMapper.insert(scheduleJob);
}
/**
* Change the status of scheduled tasks
* @param id
* @param status
*/
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void changeJobStatus(String id, Integer status) throws SchedulerException {
// EntityWrapper<ScheduleJob> wrapper = new EntityWrapper<>();
// wrapper.eq("id",id);
// String setSql = "job_status = " + status;
// this.baseMapper.updateForSet(setSql, wrapper);
ScheduleJob job = selectById(id);
if (status == 1){
// start-up
job.setJobStatus(status);
addJob(job);
} else if (status == 2) {
// stop it
deleteJob(job);
job.setJobStatus(status);
}
// Update scheduled tasks
updateById(job);
}
/**
* Update scheduled tasks cron Expression and running state
* @param jobId Scheduled task PK ID
* @param cron expression
* @param status Timing status
*/
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void updateCronStatus(String jobId, String cron, Integer status) throws SchedulerException {
ScheduleJob job = selectById(jobId);
if (status == 1){
// start-up
job.setJobStatus(status);
job.setCronExpression(cron);
addJob(job);
} else if (status == 2) {
// stop it
deleteJob(job);
job.setJobStatus(status);
job.setCronExpression(cron);
}
// Update scheduled tasks
updateById(job);
}
/**
* Add tasks
*
* @param job
* @throws SchedulerException
*/
@Transactional(propagation = Propagation.REQUIRED)
public void addJob(ScheduleJob job) throws SchedulerException {
// The running status of the scheduled task is 1 Then go to the next step
if (job == null || !Constant.STATUS_RUNNING.equals(job.getJobStatus())) {
return;
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
LogUtils.info(scheduler + ".......................................................................................add");
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// non-existent , Create a
if (null == trigger) {
Class clazz = Constant.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class : QuartzJobFactoryDisallowConcurrentExecution.class;
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", job);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} else {
// Trigger Already exists , Then update the corresponding timing settings
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// Press new cronExpression Expression rebuild trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// Press new trigger To reset job perform
scheduler.rescheduleJob(triggerKey, trigger);
}
}
@PostConstruct
public void init() throws Exception {
LogUtils.info(" Instantiation List<ScheduleJob>, Read from database ....",this);
// Get the task information data here
List<ScheduleJob> jobList = selectList(null);
for (ScheduleJob job : jobList) {
addJob(job);
}
}
/**
* Get a list of all scheduled tasks
*
* @return
* @throws SchedulerException
*/
public List<ScheduleJob> getAllJob() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
ScheduleJob job = new ScheduleJob();
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription(" trigger :" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(Integer.parseInt(triggerState.name()));
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
}
return jobList;
}
/**
* All the running job
*
* @return
* @throws SchedulerException
*/
public List<ScheduleJob> getRunningJob() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
ScheduleJob job = new ScheduleJob();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
job.setJobName(jobKey.getName());
job.setJobGroup(jobKey.getGroup());
job.setDescription(" trigger :" + trigger.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(Integer.parseInt(triggerState.name()));
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
return jobList;
}
/**
* Suspend one job
*
* @param scheduleJob
* @throws SchedulerException
*/
public void pauseJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);
}
/**
* Restore one job
*
* @param scheduleJob
* @throws SchedulerException
*/
public void resumeJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
}
/**
* Delete one job
*
* @param scheduleJob
* @throws SchedulerException
*/
public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
}
/**
* Execute now job
*
* @param scheduleJob
* @throws SchedulerException
*/
public void runAJobNow(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
}
/**
* to update job Time expression
*
* @param scheduleJob
* @throws SchedulerException
*/
public void updateJobCron(ScheduleJob scheduleJob) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, trigger);
}
}
1、 After the project is started, first run the init() Method , Query all scheduled tasks in the database table ;
2、 Then add to job Method 【addJob】, Set the state to 1 The scheduled task of is pushed to Scheduler Planned
3、 It also provides access to a list of all scheduled tasks 、 Query running job、 Suspend one job Other methods , But I haven't used it yet .
4、 This project is through mybatis-plus Perform database operations , When updating the running status , If the state is 1 Start up job, If the state is 2 Then stop job.
5、 The control layer method is omitted , According to the actual production environment .
Reference material :https://gitee.com/gangye/springboot_quartz_schedule
边栏推荐
- 2.< tag-动态规划和常规问题>lt.343. 整数拆分
- PowerShell runtime system IO exceptions
- Stm8 MCU ADC sampling function is triggered by timer
- UWB超高精度定位系统原理图
- 2022.2.17
- 为什么许多shopify独立站卖家都在用聊天机器人?一分钟读懂行业秘密!
- 微信小程序保存图片的方法
- 问题随记 —— pip 换源
- Multipass Chinese document - use packer to package multipass image
- Why do many Shopify independent station sellers use chat robots? Read industry secrets in one minute!
猜你喜欢
Dbeaver installation and configuration of offline driver
NVM installation and use and NPM package installation failure record
1.21 learning summary
Mise en œuvre du routage dynamique par zuul
Introduction to markdown grammar
超高精度定位系统中的UWB是什么
PSIM software learning ---08 call of C program block
Genius makers: lone Rangers, technology giants and AI | ten years of the rise of in-depth learning
Final review of brain and cognitive science
2022.2.17
随机推荐
Basic query
Thinkphp6 using kindeditor
Multipass Chinese document - share data with instances
PowerShell runtime system IO exceptions
Is education important or ability important in software testing
Anti withdrawal test record
Using requests library and re library to crawl web pages
UWB超高精度定位系统架构图
2022.1.23
5. <tag-栈和常规问题>补充: lt.946. 验证栈序列(同剑指 Offer 31. 栈的压入、弹出序列)
UWB超高精度定位系统原理图
2.< tag-动态规划和常规问题>lt.343. 整数拆分
Condition query
[H5 development] 03- take you hand in hand to improve H5 development - single submission vs batch submission with a common interface
[H5 development] 02 take you to develop H5 list page ~ including query, reset and submission functions
Difference between return and yield
SSH password free login, my server password free login to the other server, the other server password free login to your server
Sklearn Library -- linear regression model
Solution to back-off restarting failed container
torchvision_ Transform (image enhancement)