springboot-quartz 实现动态添加,修改,删除,暂停,恢复等功能
任务相关信息:springboot-quartz普通任务与可传参任务
一、任务实体类
package cloud.app.prod.home.quartz; import java.io.Serializable;
import java.util.Date; /**
* Author : YongBo Xie </br>
* File Name: ScheduleJob.java 任务job实体类 </br>
* Created Date: 2018年4月3日 上午11:33:47 </br>
* Modified Date: 2018年4月3日 上午11:33:47 </br>
* Version: 1.0 </br>
*/ public class ScheduleJobEntity implements Serializable { private static final long serialVersionUID = 6009097439379146309L; /** 任务ID */
private String jobId;
/** 任务名称 */
private String jobName;
/** 任务分组 */
private String jobGroup;
/** 任务运行时间表达式 */
private String cronExpression;
/** 任务类(必须是Spring中定义的Bean) */
private String targetObject;
/** 任务方法 */
private String targetMethod;
/** 是否并发 */
private boolean concurrent;
/** 触发器开始执行任务时间 */
private Date startDate;
/** 触发器结束执行任务时间 */
private Date endDate; public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getTargetObject() {
return targetObject;
}
public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
} public String getTargetMethod() {
return targetMethod;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
public boolean isConcurrent() {
return concurrent;
}
public void setConcurrent(boolean concurrent) {
this.concurrent = concurrent;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
} }
二、Spring应用上下文环境
package cloud.app.prod.home.quartz; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; /**
* Author : YongBo Xie </br>
* File Name: SpringContextUtil.java </br>
* Created Date: 2018年4月3日 上午11:27:55 </br>
* Modified Date: 2018年4月3日 上午11:27:55 </br>
* Version: 1.0 </br>
*/
@Component
public class SpringContextUtil implements ApplicationContextAware { // Spring应用上下文环境
private static ApplicationContext applicationContext; /**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
} public static ApplicationContext getApplicationContext() {
return applicationContext;
} /**
* 根据指定bean名称,获取对应的实例对象
* @param name bean的名称
* @return
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
if (applicationContext == null) {
throw new RuntimeException("spring 上下文对象未初始化,无法完成bean的查找!");
} return applicationContext.getBean(name);
} /**
* 根据指定Bean类型,获取对应的实例对象
* @param requiredType bean的class类型
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> requiredType) throws BeansException {
if (applicationContext == null) {
throw new RuntimeException("spring 上下文对象未初始化,无法完成bean的查找!");
} return applicationContext.getBean(requiredType);
} }
三、自定义MyJobFactory类,实现自动注入
package cloud.app.prod.home.quartz; import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component; /**
* Author : YongBo Xie </br>
* File Name: MyJobFactory.java </br>
* Created Date: 2018年4月2日 下午3:27:30 </br>
* Modified Date: 2018年4月2日 下午3:27:30 </br>
* Version: 1.0 </br>
*/
@Component
public class MyJobFactory extends AdaptableJobFactory { @Autowired
private AutowireCapableBeanFactory capableBeanFactory; @Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
// 进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
四、配置SchedulerFactoryBean
package cloud.app.prod.home.quartz; import java.io.IOException;
import java.util.Properties; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean; import cloud.app.prod.home.quartz.MyJobFactory; /**
* Author : YongBo Xie </br>
* File Name: QuartzConfigration.java </br>
* Created Date: 2018年3月31日 下午3:42:04 </br>
* Modified Date: 2018年3月31日 下午3:42:04 </br>
* Version: 1.0 </br>
*/
@Configuration
@EnableScheduling
public class QuartzConfigration { @Autowired
private MyJobFactory myJobFactory; @Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean(); // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
factory.setOverwriteExistingJobs(true); // 延时启动,应用启动1秒后
// factory.setStartupDelay(1); // 加载quartz数据源配置
// factory.setQuartzProperties(quartzProperties()); // 自定义Job Factory,用于Spring注入
factory.setJobFactory(myJobFactory); return factory;
} /**
* 加载quartz数据源配置
*
* @return
* @throws IOException
*/
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}
五、定时任务公共操作类
package cloud.app.prod.home.quartz; import java.util.ArrayList;
import java.util.List;
import java.util.Map; import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.utils.DSHUtils; /**
* Author : YongBo Xie </br>
* File Name: QuartzUtil.java </br>
* Created Date: 2018年4月3日 上午10:58:32 </br>
* Modified Date: 2018年4月3日 上午10:58:32 </br>
* Version: 1.0 </br>
*/ public class QuartzUtil { private static Logger logger = Logger.getLogger(QuartzUtil.class); public static List<String> jobNames = new ArrayList<String>(); public static String getScheduleJobName(String jobName) {
if (jobNames.contains(jobName)) {
return jobName;
}
return null;
} /**
* 创建一个定时任务,并做安排(用于继承job类的执行方法)
*
* @param scheduler
* @param scheduleJob
* @param paramsMap
* @param jobClass
* @throws FailException
*/
public static void createSheduler(Scheduler scheduler, ScheduleJobEntity scheduleJob, Map<String, Object> paramsMap, Class<? extends Job> jobClass) throws FailException {
try {
logger.info("----- scheduling job --------"); // 创建一项作业
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.build(); // 设置参数
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
jobDetail.getJobDataMap().put(entry.getKey(), entry.getValue());
} // 作业的执行时间(当前时间的下一分钟)
// Date runTime = DateBuilder.evenMinuteDate(new Date()); // 创建一个触发器
CronTrigger trigger = null;
if (null != scheduleJob.getStartDate() && null != scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.startAt(scheduleJob.getStartDate()) // 该触发器开始执行作业时间
.endAt(scheduleJob.getEndDate()) // 该触发器结束作业时间
.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())) // 具体执行时间
.build();
} else if (null != scheduleJob.getStartDate() && null == scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.startAt(scheduleJob.getStartDate()) // 该触发器开始执行作业时间
.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())) // 具体执行时间
.build();
} else if (null == scheduleJob.getStartDate() && null != scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.endAt(scheduleJob.getEndDate()) // 该触发器结束作业时间
.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())) // 具体执行时间
.build();
} else {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())) // 具体执行时间
.build();
} // 告诉调度器使用该触发器来安排作业
scheduler.scheduleJob(jobDetail, trigger);
// 启动调度器
scheduler.start();
logger.info("------ started scheduler -------"); logger.info("------ waiting 2 minutes ------");
Thread.sleep(2 * 60 * 1000); // logger.info("------- shutting down ------");
// // 关闭调度器
// scheduler.shutdown(true);
// logger.info("------- shutdown complete -------");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 创建一个定时任务,并做安排(用于自定义执行方法)
*
* @param scheduler
* @param scheduleJob
* @param paramsMap
* @throws FailException
*/
public static void createSheduler(Scheduler scheduler, ScheduleJobEntity scheduleJob, Map<String, Object> paramsMap) throws FailException {
try {
// 新建一个基于Spring的管理Job类
MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
// 设置Job组名称
methodInvJobDetailFB.setGroup(scheduleJob.getJobGroup());
// 设置Job名称
methodInvJobDetailFB.setName(scheduleJob.getJobName());
// 设置任务类
methodInvJobDetailFB.setTargetObject(SpringContextUtil.getApplicationContext().getBean(scheduleJob.getTargetObject()));
// 设置任务方法
methodInvJobDetailFB.setTargetMethod(scheduleJob.getTargetMethod());
// 将管理Job类提交到计划管理类
methodInvJobDetailFB.afterPropertiesSet();
// 并发设置
methodInvJobDetailFB.setConcurrent(scheduleJob.isConcurrent()); JobDetail jobDetail = methodInvJobDetailFB.getObject();// 动态 // 设置参数
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
jobDetail.getJobDataMap().put(entry.getKey(), entry.getValue());
} // jobName存入到队列 每隔一段时间就会扫描所以需要时检测
if (!QuartzUtil.jobNames.contains(scheduleJob.getJobName())) {
QuartzUtil.jobNames.add(scheduleJob.getJobName());
} // 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = null;
if (null != scheduleJob.getStartDate() && null != scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.startAt(scheduleJob.getStartDate()) // 该触发器开始执行作业时间
.endAt(scheduleJob.getEndDate()) // 该触发器结束作业时间
.withSchedule(scheduleBuilder) // 具体执行时间
.build();
} else if (null != scheduleJob.getStartDate() && null == scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.startAt(scheduleJob.getStartDate()) // 该触发器开始执行作业时间
.withSchedule(scheduleBuilder) // 具体执行时间
.build();
} else if (null == scheduleJob.getStartDate() && null != scheduleJob.getEndDate()) {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.endAt(scheduleJob.getEndDate()) // 该触发器结束作业时间
.withSchedule(scheduleBuilder) // 具体执行时间
.build();
} else {
trigger = (CronTrigger) TriggerBuilder.newTrigger()
.withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup())
.withSchedule(scheduleBuilder) // 具体执行时间
.build();
} // 暂时停止 任务都安排完之后统一启动 解决耗时任务按照顺序部署后执行紊乱的问题
// scheduler.standby();
// 注入到管理类
scheduler.scheduleJob(jobDetail, trigger);
logger.info(scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "创建完毕");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 修改定时任务
* @param scheduler
* @param scheduleJob
* @param triggerKey
* @param trigger
* @throws FailException
*/
public static void updateScheduler(Scheduler scheduler, ScheduleJobEntity scheduleJob, TriggerKey triggerKey, CronTrigger trigger) throws FailException {
try {
if (!trigger.getCronExpression().equalsIgnoreCase(scheduleJob.getCronExpression())) {
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
logger.info(scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + " 更新完毕,目前cron表达式为:"
+ scheduleJob.getCronExpression() + " concurrent: " + scheduleJob.isConcurrent());
}
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 删除定时任务
* @param scheduler
* @param triggerKey
* @param trigger
* @throws FailException
*/
public static void deleteScheduler(Scheduler scheduler, TriggerKey triggerKey, CronTrigger trigger) throws FailException {
try {
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(trigger.getJobKey());// 删除任务
logger.info(triggerKey.getGroup() + "." + triggerKey.getName() + "删除完毕");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 暂停定时任务
* @param scheduler
* @param trigger
* @throws FailException
*/
public static void pauseScheduler(Scheduler scheduler, CronTrigger trigger) throws FailException {
try {
scheduler.pauseJob(trigger.getJobKey());// 暂停任务
logger.info(trigger.getJobKey().getGroup() + "." + trigger.getJobKey().getName() + "暂停完毕");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 恢复定时任务
* @param scheduler
* @param trigger
* @throws FailException
*/
public static void resumeScheduler(Scheduler scheduler, CronTrigger trigger) throws FailException {
try {
scheduler.resumeJob(trigger.getJobKey());// 恢复任务
logger.info(trigger.getJobKey().getGroup() + "." + trigger.getJobKey().getName() + "恢复完毕");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} /**
* 立即执行定时任务
* @param scheduler
* @param trigger
* @throws FailException
*/
public static void triggerScheduler(Scheduler scheduler, CronTrigger trigger) throws FailException {
try {
scheduler.triggerJob(trigger.getJobKey());// 立即执行任务
logger.info(trigger.getJobKey().getGroup() + "." + trigger.getJobKey().getName() + "立即执行完毕");
} catch (Exception e) {
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
} }
六、具体任务操作类
package cloud.app.prod.home.quartz.mem; import java.util.HashMap;
import java.util.Map; import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Scheduler;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.mem.vo.MarketingActivitiesVO;
import cloud.app.prod.home.quartz.QuartzUtil;
import cloud.app.prod.home.quartz.ScheduleJobEntity;
import cloud.app.prod.home.utils.DSHUtils; /**
* Author : YongBo Xie </br>
* File Name: ScheduleRefreshDatabase.java </br>
* Created Date: 2018年3月31日 下午3:58:08 </br>
* Modified Date: 2018年3月31日 下午3:58:08 </br>
* Version: 1.0 </br>
*/
@Component
@DisallowConcurrentExecution // 任务同步
public class MarketingActivityScheduleHandle { private static Logger logger = Logger.getLogger(MarketingActivityScheduleHandle.class); @Autowired
private SchedulerFactoryBean schedulerFactoryBean;
// 公用Scheduler,同一个对象
// public static Scheduler scheduler = (Scheduler) SpringContextUtil.getApplicationContext().getBean("schedulerFactoryBean"); @Scheduled(fixedRate = 5000) // 每隔5s查库
// @Scheduled(cron = "0 0 1 * * ?")
public void scheduleRefreshCron() throws FailException {
try{
logger.info("----- scheduling job --------"); String searchCron = "*/5 * * * * ?";// 从数据库查询出来的 // 获取一个调度器
// SchedulerFactory factory = new StdSchedulerFactory();
// Scheduler scheduler = factory.getScheduler();
Scheduler scheduler = schedulerFactoryBean.getScheduler(); // 设置参数
MarketingActivitiesVO marketingActivitiesVO = new MarketingActivitiesVO();
marketingActivitiesVO.setId(DSHUtils.generateUUID()); ScheduleJobEntity scheduleJob = new ScheduleJobEntity();
scheduleJob.setJobId(marketingActivitiesVO.getId());
scheduleJob.setJobName("marketingActivity");
scheduleJob.setJobGroup("marketingActivityGroup");
scheduleJob.setCronExpression(searchCron);
scheduleJob.setTargetObject("marketingActivityScheduleTask");
scheduleJob.setTargetMethod("executeInternal");
scheduleJob.setConcurrent(true); Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("marketingActivitiesVO", marketingActivitiesVO); // 获取triggerKey
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
// 获取trigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 不存在,创建一个
if (null == trigger) {
// 创建一个触发器
QuartzUtil.createSheduler(scheduler, scheduleJob, paramsMap, MarketingActivityScheduleTask.class);
// QuartzUtil.createSheduler(scheduler, scheduleJob, paramsMap);
} else {// Trigger已存在,那么更新相应的定时设置
QuartzUtil.updateScheduler(scheduler, scheduleJob, triggerKey, trigger); // 删除
QuartzUtil.deleteScheduler(scheduler, triggerKey, trigger);
}
}catch(Exception e){
logger.error(DSHUtils.formatException(e));
throw new FailException(e.getMessage());
}
}
}
七:1)、具体任务执行类(继承Job)
package cloud.app.prod.home.quartz.mem; import org.apache.log4j.Logger;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException;
import cloud.app.prod.home.mem.vo.MarketingActivitiesVO;
import cloud.app.prod.home.rabbitmq.mem.MarketingActivitieRabbitMqSender; /**
* Author : YongBo Xie </br>
* File Name: ScheduleTask.java </br>
* Created Date: 2018年3月31日 下午3:37:43 </br>
* Modified Date: 2018年3月31日 下午3:37:43 </br>
* Version: 1.0 </br>
*/
@Component // 此注解必加
@EnableScheduling // 此注解必加
public class MarketingActivityScheduleTask extends QuartzJobBean { private static Logger logger = Logger.getLogger(MarketingActivityScheduleTask.class);
@Autowired
private MarketingActivitieRabbitMqSender marketingActivitieRabbitMqSender; @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info("execute activity");
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
MarketingActivitiesVO marketingActivitiesVO = (MarketingActivitiesVO) dataMap.get("marketingActivitiesVO");
logger.info("marketingActivitiesVO.id: " + marketingActivitiesVO.getId());
try {
logger.info("marketingActivitieRabbitMqSender: " + marketingActivitieRabbitMqSender);
marketingActivitieRabbitMqSender.sendRabbitmqDirect(marketingActivitiesVO);
} catch (FailException e) {
e.printStackTrace();
}
} }
package cloud.app.prod.home.quartz.mem; import org.apache.log4j.Logger;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component; import cloud.app.prod.home.common.FailException; /**
* Author : YongBo Xie </br>
* File Name: ScheduleTask.java </br>
* Created Date: 2018年3月31日 下午3:37:43 </br>
* Modified Date: 2018年3月31日 下午3:37:43 </br>
* Version: 1.0 </br>
*/
@Configuration
@Component // 此注解必加
@EnableScheduling // 此注解必加
public class ScheduleTask { private static Logger logger = Logger.getLogger(ScheduleTask.class); public void marketingActivity() throws FailException {
logger.info("execute activity");
} }
springboot-quartz 实现动态添加,修改,删除,暂停,恢复等功能的更多相关文章
- SpringBoot定时任务升级篇(动态添加修改删除定时任务)
需求缘起:在发布了<Spring Boot定时任务升级篇>之后得到不少反馈,其中有一个反馈就是如何动态添加修改删除定时任务?那么我们一起看看具体怎么实现,先看下本节大纲: (1)思路说明: ...
- quartz.net动态添加job
quartz.net动态添加job设计-(五) 介绍 在实际项目使用中quartz.net中,都希望有一个管理界面可以动态添加job,而避免每次都要上线发布. 也看到有园子的同学问过.这里就介绍下实现 ...
- Unity NGUI中动态添加和删除sprite
(以后,参考链接和作者将在文章首部给出,转载请保留此部分内容) 参考链接:http://www.narkii.com/club/thread-299977-1.html,作者:纳金网 比巴卜: 参考链 ...
- 打通前后端全栈开发node+vue进阶【课程学习系统项目实战详细讲解】(3):用户添加/修改/删除 vue表格组件 vue分页组件
第三章 建议学习时间8小时 总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章] 演示地址:后台:demo ...
- adoop集群动态添加和删除节点
hadoop集群动态添加和删除节点说明 上篇博客我已经安装了Hadoop集群(hadoop集群的安装步骤和配置),现在写这个博客我将在之前的基础上进行节点的添加的删除. 首先将启动四台机器(一主三从) ...
- 【转】C#添加修改删除文件文件夹大全
[转]C#添加修改删除文件文件夹大全 C#添加修改删除文件文件夹大全 StreamWriter sw = File.AppendText(Server.MapPath(".")+& ...
- JS实现动态添加和删除div
实现方式一:只在最后一个数据中动态添加或者删除 | 背景需要做一个页面,页面可以输入参数,点击确认按钮可以发请求给某接口.但是接口的某个字段是数组类型,所以在页面上需要实现添加或者删除元素的功能. | ...
- JavaWeb_day03_员工信息添加修改删除
day03员工的添加,修改,删除 修改功能 思路 : 点击修改员工数据之后,跳转到单行文本,查询要修改的员工id的全部信息,主键id设置为readonly,其余的都可以修改, 修改之后,提交按钮,提交 ...
- 插件~使用ECharts动态在地图上标识点~动态添加和删除标识点
之前写过一个Echarts的文章,没有基础的同学可以先看这<上一篇>,对于一个地图和说,我们在初始化之后,你可能被在地图上标识出一些点,当然这根据你的业务去标识,而如果每次更新数据都加载全 ...
- [Flex] Accordion系列-动态添加或删除Accordion容器中项目
<?xml version="1.0" encoding="utf-8"?> <!--Flex中如何使用addChild()和removeCh ...
随机推荐
- AP聚类
基于代表点的聚类算法可以说是聚类算法中"最经典的,最流行的,也是最前沿的". "最经典"是因为K均值是最早出现的聚类算法之一; "最流行"是 ...
- 如何用putty链接服务器端,并安装wdcp
首先把自己阿里云的磁盘格式化然后重启 自己下载一个PuTTY 打开后输入自己的Ip地址端口号默认是22 会跳出一个yes 跟no界面,点击yes 会进入一个类似cmd界面 直接输入root,然后会提示 ...
- windows下使用批处理设置环境变量
1. 设置临时环境变量 set BAT_HOME=c:\bat 此命令只对当前窗口有效,批处理或cmd窗口一关闭,变量就恢复原来的值了. 2. 设置永久环境变量 方法一 setx BAT_HOME C ...
- css中有些属性的前面会加上“*”或“_(兼容IE浏览器)
给不同浏览器识别: color{ background-color: #CC00FF; /*所有浏览器都会显示为紫色*/ background-color: #FF0000\9; /*IE6.IE7. ...
- PAT_A1114#Family Property
Source: PAT A1114 Family Property (25 分) Description: This time, you are supposed to help us collect ...
- HDU 3152 Obstacle Course(优先队列,广搜)
题目 用优先队列优化普通的广搜就可以过了. #include<stdio.h> #include<string.h> #include<algorithm> usi ...
- js for 循环 添加tr td 算法
StringBuffer sb=new StringBuffer(); int n = 5; sb.append("<tr>"); List<MenuBean&g ...
- STL中队列queue的用法
头文件:#include <queue> 建立一个队列queue < 类型 > q 加入一个新的元素q.push(a) 询问队首元素q.front() 弹出队首元素q.pop( ...
- String s="a"+"b"+"c"+"d";创建了几个对象?
对于如下代码: package reviewTest; /** * @ClassName: StringTest * @Description: 测试String的字符串相加优化 * @author ...
- Django REST framework 内置访问频率控制
对匿名用户采用 IP 控制访问频率,对登录用户采用 用户名 控制访问频率. from rest_framework.throttling import SimpleRateThrottle class ...