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 + ...
随机推荐
- ThinkPHP3.2.2的函数扩展
ThinkPHP的函数扩展:为了更好的在前台模板中显示变量,例如,商品分类中,分类名称之间的缩进.此时,在APP/Common/Common文件夹下(APP为新建的应用目录),新建一个php文件,如: ...
- Spring Boot Mybatis 使用教程
Mybatis 在当下互联网开发环境,十分重要.本章主要讲述 Mybatis 如何使用. 从本系列开始,都需要用到 mysql 数据库 和其他一些参考的数据库.请准备相关环节.本章需要以下环境支撑: ...
- Hibernate学习(四)
一对多测试案例 1.类图 2.创建表 drop table if exists t_student ; drop table if exists t_class ; create table t_cl ...
- 吴裕雄 python 神经网络——TensorFlow 图像处理函数
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt image_raw_data = tf.gfile ...
- 【原】python总结
python3浅拷贝和深拷贝:https://www.jianshu.com/p/c7e72fcad407
- (0)Lora及LoraWAN
Lora和LoraWAN的区别 LoRa经常被误用来描述整个LPWAN通信系统,其实Lora是Semtech拥有的专有调制格式. SX1272和SX1276 LoRa芯片使用称为chirp扩频(CSS ...
- 国外最受欢迎的15个BT下载网站
1.EYH.BIZ 海盗湾(The Pirate Bay)现在在中国成立的一个分部 www.eyh.biz 一个提供BT种子文件和链接,以方便使用BT协议的对等文件共享网站.该网站于2003年在瑞典创 ...
- OS(操作系统)结构
1.整体式: 模块设计(独立的) 调用自由 用全局变量来通信 缺点:信息不安全,维护更新比较难 2.层次结构(典型的如TCP/IP协议): 所有的模块排成若干层,相邻的互相依赖调用 按调用次序来安排 ...
- 每个 JavaScript 开发者都该懂的 Unicode
英文原文标题:what-every-javascript-developer-should-know-about-unicode (译者注:本文含有Unicode辅助平面的特殊字符,部分浏览器可能无法 ...
- GO闭包
package main import "fmt" func main() { add_func := add(1,2) fmt.Println(add_func(1,1)) fm ...