当前位置:网站首页>[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
边栏推荐
- [H5 development] 01 take you to experience H5 development from a simple page ~ the whole page implementation process from static page to interface adjustment manual teaching
- 1.21 learning summary
- Multipass Chinese documents - improve mount performance
- File upload and security dog
- Genius makers: lone Rangers, technology giants and AI | ten years of the rise of in-depth learning
- 2.9 learning summary
- BACK-OFF RESTARTING FAILED CONTAINER 的解决方法
- [H5 development] 02 take you to develop H5 list page ~ including query, reset and submission functions
- 广和通联合安提国际为基于英伟达 Jetson Xavier NX的AI边缘计算平台带来5G R16强大性能
- 86.(cesium篇)cesium叠加面接收阴影效果(gltf模型)
猜你喜欢

Advanced learning of MySQL (learning from Shang Silicon Valley teacher Zhou Yang)

Illustration of ONEFLOW's learning rate adjustment strategy

2022.1.24

1.11 learning summary

2.22.2.14

How can the intelligent transformation path of manufacturing enterprises be broken due to talent shortage and high cost?

YOLOV5超参数设置与数据增强解析

1.18 learning summary

Text horizontal alignment attribute text align and element vertical alignment attribute vertical align

Mise en œuvre du routage dynamique par zuul
随机推荐
-Discrete Mathematics - Analysis of final exercises
Differences between TCP and UDP
YOLOV5训练结果的解释
Multipass Chinese document - use multipass service to authorize the client
1.24 learning summary
Zhongshanshan: engineers after being blasted will take off | ONEFLOW u
1.14 learning summary
1.21 learning summary
[IDE(ImageBed)]Picgo+Typora+aliyunOSS部署博客图床(2022.6)
Modify the case of the string title(), upper(), lower()
Multipass中文文档-设置驱动
Illustration of ONEFLOW's learning rate adjustment strategy
ThreadPoolExecutor implements file uploading and batch inserting data
202.2.9
torchvision_ Transform (image enhancement)
排序查询
Multipass中文文档-使用Multipass服务授权客户端
Mise en œuvre du routage dynamique par zuul
Create a binary response variable using the cut sub box operation
YOLOV5超参数设置与数据增强解析