quartz spring 实现动态定时任务
在实际项目应用中经常会用到定时任务,可以通过quartz和spring的简单配置即可完成,但如果要改变任务的执行时间、频率,废弃任务等就需要改变配置甚至代码需要重启服务器,这里介绍一下如何通过quartz与spring的组合实现动态的改变定时任务的状态的一个实现。
本文章适合对quartz和spring有一定了解的读者。
spring版本为3.2 quartz版本为2.2.1 如果使用了quartz2.2.1 则spring版本需3.1以上
源碼在文件下載
1.
spring中引入注册bean
- <bean id="schedulerFactoryBean"
- class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
为什么要与spring结合?
与spring结合可以使用spring统一管理quartz中任务的生命周期,使得web容器关闭时所有的任务一同关闭。如果不用spring管理可能会出现web容器关闭而任务仍在继续运行的情况,不与spring结合的话要自己控制任务在容器关闭时一起关闭。
2.创建保存计划任务信息的实体类
- /**
- *
- * @Description: 计划任务信息
- * @author snailxr
- * @date 2014年4月24日 下午10:49:43
- */
- public class ScheduleJob {
- public static final String STATUS_RUNNING = "1";
- public static final String STATUS_NOT_RUNNING = "0";
- public static final String CONCURRENT_IS = "1";
- public static final String CONCURRENT_NOT = "0";
- private Long jobId;
- private Date createTime;
- private Date updateTime;
- /**
- * 任务名称
- */
- private String jobName;
- /**
- * 任务分组
- */
- private String jobGroup;
- /**
- * 任务状态 是否启动任务
- */
- private String jobStatus;
- /**
- * cron表达式
- */
- private String cronExpression;
- /**
- * 描述
- */
- private String description;
- /**
- * 任务执行时调用哪个类的方法 包名+类名
- */
- private String beanClass;
- /**
- * 任务是否有状态
- */
- private String isConcurrent;
- /**
- * spring bean
- */
- private String springId;
- /**
- * 任务调用的方法名
- */
- private String methodName;
- //get set.......
- }
/**
*
* @Description: 计划任务信息
* @author snailxr
* @date 2014年4月24日 下午10:49:43
*/
public class ScheduleJob {
public static final String STATUS_RUNNING = "1";
public static final String STATUS_NOT_RUNNING = "0";
public static final String CONCURRENT_IS = "1";
public static final String CONCURRENT_NOT = "0";
private Long jobId;
private Date createTime;
private Date updateTime;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务状态 是否启动任务
*/
private String jobStatus;
/**
* cron表达式
*/
private String cronExpression;
/**
* 描述
*/
private String description;
/**
* 任务执行时调用哪个类的方法 包名+类名
*/
private String beanClass;
/**
* 任务是否有状态
*/
private String isConcurrent;
/**
* spring bean
*/
private String springId;
/**
* 任务调用的方法名
*/
private String methodName;
//get set.......
}
该实体类与数据库中的表对应,在数据库中存储多个计划任务。
注意:jobName 跟 groupName的组合应该是唯一的,beanClass springId至少有一个
在项目启动时运行以下代码:
- public void init() throws Exception {
- Scheduler scheduler = schedulerFactoryBean.getScheduler();
- // 这里从数据库中获取任务信息数据
- List<ScheduleJob> jobList = scheduleJobMapper.getAll();
- for (ScheduleJob job : jobList) {
- addJob(job);
- }
- }
public void init() throws Exception {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
// 这里从数据库中获取任务信息数据
List<ScheduleJob> jobList = scheduleJobMapper.getAll();
for (ScheduleJob job : jobList) {
addJob(job);
}
}
- /**
- * 添加任务
- *
- * @param scheduleJob
- * @throws SchedulerException
- */
- public void addJob(ScheduleJob job) throws SchedulerException {
- if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
- return;
- }
- Scheduler scheduler = schedulerFactoryBean.getScheduler();
- log.debug(scheduler + ".......................................................................................add");
- TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
- CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
- // 不存在,创建一个
- if (null == trigger) {
- Class clazz = ScheduleJob.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已存在,那么更新相应的定时设置
- CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
- // 按新的cronExpression表达式重新构建trigger
- trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
- // 按新的trigger重新设置job执行
- scheduler.rescheduleJob(triggerKey, trigger);
- }
- }
/**
* 添加任务
*
* @param scheduleJob
* @throws SchedulerException
*/
public void addJob(ScheduleJob job) throws SchedulerException {
if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
return;
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
log.debug(scheduler + ".......................................................................................add");
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
Class clazz = ScheduleJob.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已存在,那么更新相应的定时设置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
看到代码第20行根据scheduleJob类中CONCURRENT_IS来判断任务是否有状态。来给出不同的Job实现类
- /**
- *
- * @Description: 若一个方法一次执行不完下次轮转时则等待改方法执行完后才执行下一次操作
- * @author snailxr
- * @date 2014年4月24日 下午5:05:47
- */
- @DisallowConcurrentExecution
- public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
- public final Logger log = Logger.getLogger(this.getClass());
- @Override
- public void execute(JobExecutionContext context) throws JobExecutionException {
- ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
- TaskUtils.invokMethod(scheduleJob);
- }
- }
/**
*
* @Description: 若一个方法一次执行不完下次轮转时则等待改方法执行完后才执行下一次操作
* @author snailxr
* @date 2014年4月24日 下午5:05:47
*/
@DisallowConcurrentExecution
public class QuartzJobFactoryDisallowConcurrentExecution implements Job {
public final Logger log = Logger.getLogger(this.getClass());
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
- /**
- *
- * @Description: 计划任务执行处 无状态
- * @author snailxr
- * @date 2014年4月24日 下午5:05:47
- */
- public class QuartzJobFactory implements Job {
- public final Logger log = Logger.getLogger(this.getClass());
- @Override
- public void execute(JobExecutionContext context) throws JobExecutionException {
- ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
- TaskUtils.invokMethod(scheduleJob);
- }
- }
/**
*
* @Description: 计划任务执行处 无状态
* @author snailxr
* @date 2014年4月24日 下午5:05:47
*/
public class QuartzJobFactory implements Job {
public final Logger log = Logger.getLogger(this.getClass());
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}
真正执行计划任务的代码就在TaskUtils.invokMethod(scheduleJob)里面
通过scheduleJob的beanClass或springId通过反射或spring来获得需要执行的类,通过methodName来确定执行哪个方法
- public class TaskUtils {
- public final static Logger log = Logger.getLogger(TaskUtils.class);
- /**
- * 通过反射调用scheduleJob中定义的方法
- *
- * @param scheduleJob
- */
- public static void invokMethod(ScheduleJob scheduleJob) {
- Object object = null;
- Class clazz = null;
- //springId不为空先按springId查找bean
- if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
- object = SpringUtils.getBean(scheduleJob.getSpringId());
- } else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
- try {
- clazz = Class.forName(scheduleJob.getBeanClass());
- object = clazz.newInstance();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if (object == null) {
- log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");
- return;
- }
- clazz = object.getClass();
- Method method = null;
- try {
- method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
- } catch (NoSuchMethodException e) {
- log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if (method != null) {
- try {
- method.invoke(object);
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
public class TaskUtils {
public final static Logger log = Logger.getLogger(TaskUtils.class);
/**
* 通过反射调用scheduleJob中定义的方法
*
* @param scheduleJob
*/
public static void invokMethod(ScheduleJob scheduleJob) {
Object object = null;
Class clazz = null;
//springId不为空先按springId查找bean
if (StringUtils.isNotBlank(scheduleJob.getSpringId())) {
object = SpringUtils.getBean(scheduleJob.getSpringId());
} else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
try {
clazz = Class.forName(scheduleJob.getBeanClass());
object = clazz.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (object == null) {
log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");
return;
}
clazz = object.getClass();
Method method = null;
try {
method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
} catch (NoSuchMethodException e) {
log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (method != null) {
try {
method.invoke(object);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
对任务的暂停,删除,修改等操作
- **
- * 获取所有计划中的任务列表
- *
- * @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.getKey());
- Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
- job.setJobStatus(triggerState.name());
- if (trigger instanceof CronTrigger) {
- CronTrigger cronTrigger = (CronTrigger) trigger;
- String cronExpression = cronTrigger.getCronExpression();
- job.setCronExpression(cronExpression);
- }
- jobList.add(job);
- }
- }
- return jobList;
- }
- /**
- * 所有正在运行的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.getKey());
- Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
- job.setJobStatus(triggerState.name());
- if (trigger instanceof CronTrigger) {
- CronTrigger cronTrigger = (CronTrigger) trigger;
- String cronExpression = cronTrigger.getCronExpression();
- job.setCronExpression(cronExpression);
- }
- jobList.add(job);
- }
- return jobList;
- }
- /**
- * 暂停一个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);
- }
- /**
- * 恢复一个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);
- }
- /**
- * 删除一个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);
- }
- /**
- * 立即执行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);
- }
- /**
- * 更新job时间表达式
- *
- * @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);
- }
**
* 获取所有计划中的任务列表
*
* @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.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
}
return jobList;
}
/**
* 所有正在运行的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.getKey());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
job.setJobStatus(triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
job.setCronExpression(cronExpression);
}
jobList.add(job);
}
return jobList;
}
/**
* 暂停一个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);
}
/**
* 恢复一个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);
}
/**
* 删除一个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);
}
/**
* 立即执行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);
}
/**
* 更新job时间表达式
*
* @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);
}
小提示
更新表达式,判断表达式是否正确可用一下代码
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("xxxxx");
抛出异常则表达式不正确
quartz spring 实现动态定时任务的更多相关文章
- Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定). 这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户 ...
- springboot和quartz整合实现动态定时任务(持久化单节点)
Quartz是一个完全由java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,它支持定时任务持久化到数据库,从而避免了重启服务器时任务丢失,支持分布式多节点,大大的 ...
- Spring设置动态定时任务
1.在Spring中经常会用到定时任务,一般会在业务方法上使用@Schedule(cron="定时执行规则"),无法实现从前台动态设置定时任务. 在java中固定频率的任务使用Sc ...
- Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置
Spring整合quartz2.2.3总结,quartz动态定时任务,Quartz定时任务集群配置 >>>>>>>>>>>>&g ...
- spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】
最近做了一个spring boot 整合 quartz 实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要 ...
- Quartz在Spring中动态设置cronExpression
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定). 这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文 ...
- Spring Boot 创建定时任务(配合数据库动态执行)
序言:创建定时任务非常简单,主要有两种创建方式:一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer). 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库 ...
- spring多个定时任务quartz配置
spring多个定时任务quartz配置 <?xml version=”1.0″ encoding=”UTF-8″?> <beans xmlns=”http://www.spring ...
- 使用spring+quartz配置多个定时任务
Spring被用在了越来越多的项目中, quartz也被公认为是比较好用的定时器设置工具, 在这里通过一个demo说明如何使用spring和quartz配置多个定时任务. 环境: eclipse + ...
随机推荐
- springboot:配置多个数据源
参考:还未整理 https://www.cnblogs.com/carrychan/p/9401471.html https://www.cnblogs.com/lijianda/p/11022892 ...
- spark报错 java.lang.NoClassDefFoundError: scala/xml/MetaData
代码: 报错信息: java.lang.NoClassDefFoundError: scala/xml/MetaData 原因:确失jar包 <dependency> <groupI ...
- jquery发送请求的各种方法
地址链接:https://www.cnblogs.com/java-dyb/p/10910566.html 关于向服务器传递数据的一些补充: json字符串与json对象之间的转换: JSON.par ...
- SpringMvc 项目配置
spring-mvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&quo ...
- 电子书及阅读器Demo
电子书阅读器(Kindle,电子纸技术.LCD.电子墨水技术等: 亚马逊/当当网站) 电子书产业可分5大环节:内容供应商.数字格式制作商.内容流通服务平台.传输平台以及终端阅读器产品. 全球电子书市 ...
- video兼容ie,ckplayer网页播放器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- #P4770 [NOI2018]你的名字 的题解
题目背景 实力强大的小A 被选为了ION2018 的出题人,现在他需要解决题目的命名问题. 题目描述 小A 被选为了ION2018 的出题人,他精心准备了一道质量十分高的题目,且已经把除了题目命名以外 ...
- 数据包报文格式(IP包、TCP报头、UDP报头)
转自: https://blog.51cto.com/lyhbwwk/2162568 一.IP包格式 IP数据包是一种可变长分组,它由首部和数据负载两部分组成.首部长度一般为20-60字节(Byte) ...
- poj1988 Cube Stacking(并查集
题目地址:http://poj.org/problem?id=1988 题意:共n个数,p个操作.输入p.有两个操作M和C.M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[ ...
- 3_03_MSSQL课程_Ado.Net_数据导入
数据库数据导出和导入 思路: --思路: 1.找到文件 2.读取文件 3.第一行 忽略 4.insert using System; using System.Collections.Generic; ...