项目中很多时候需要用到应用启动时做的事情,比如说启动时刷新redis等缓存,启动时开启一个socket监听,这些都是很常见很基础的应用.
直接上代码:
/**
* 应用启动后的初始化类
* @author Raines
*
*/
@Component
public class RmsIniter implements CommandLineRunner{
@SuppressWarnings("unchecked")
public void run(String... args) throws Exception {
//项目启动时加载该方法
}
}
谈一下最近遇到的一个问题及解决方案:
问题:用到定时任务Quartz的springboot项目中,当项目重启后定时任务会清空,要求项目重启后未执行的定时任务继续执行
(定时任务框架版本为Quartz-2.2.1)
/**
* 应用启动后的初始化类
* @author Raines
*
*/
@Component
public class RmsIniter implements CommandLineRunner,RmsIniterInterface {
@SuppressWarnings("unchecked")
public void run(String... args) throws Exception {
// 查询暂存的定时任务
Map pm = new HashMap<>();
pm.put("tServer", RMS_SHORT);
List l = tTimeTaskService.find(pm);
// 初始化暂存的定时任务
initTimeTask(l);
}
/**
* 初始化暂存的定时任务
* @param l 要初始化的任务列表
*/
private void initTimeTask(List l) {
log.info("开始初始化定时任务");
for (TTimeTask tTimeTask : l) {
if(PlanJob.class.getName().equals(tTimeTask.gettClass())) {
initPlanJob(tTimeTask);
} else if(UnPlanJob.class.getName().equals(tTimeTask.gettClass())) {
initUnPlanJob(tTimeTask);
} else if(SlipPlanJob.class.getName().equals(tTimeTask.gettClass())) {
initSlipPlanJob(tTimeTask);
}
}
}
/**
* 初始化班车发车计划
* @param t 任务对象
*/
private void initPlanJob(TTimeTask t) {
//此处判断定时任务是否要执行;如果当前时间超过定时任务执行时间,则立即执行;如果当前时间没有超时,则新建定时任务(此处需要留一些程序执行时间)
}
}
以下是定时任务工具类:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* 定时任务工具类
* @author Raines
*/
@Configuration
public class QuartzManager {
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
/**
* 立即执行任务
* @param taskName 任务名
*/
public static void nowDo(String taskName){
try {
Scheduler sched = schedulerFactory.getScheduler();
//第二个参数为组名,新增任务时组名与任务名相同
//通过任务名与组名可以找到唯一一个定时任务,也就是jobkey
JobKey jobKey = new JobKey(taskName,taskName);
//传入jobkey,立即执行
sched.triggerJob(jobKey);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* @Description: 添加一个定时任务
*
* @param jobClass 任务
* @param cron 时间设置,参考quartz说明文档
* @param map 需要传递的数据键值对
* @param taskName 任务名称,不传时将自动生成uuid作为名称
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void addJob(Class jobClass, String cron, Map map, String taskName) {
try {
Scheduler sched = schedulerFactory.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(taskName, taskName).build();
jobDetail.getJobDataMap().putAll(map);
jobDetail.getJobDataMap().put("uuid",taskName);
// 触发器
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(taskName, taskName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置JobDetail和Trigger
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一个任务的触发时间
*
* @param cron 时间设置,参考quartz说明文档
*/
public static void modifyJobTime(String uuid,String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(uuid, uuid);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
/** 方式一 :调用 rescheduleJob 开始 */
// 触发器
TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(uuid, uuid);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
sched.rescheduleJob(triggerKey, trigger);
/** 方式一 :调用 rescheduleJob 结束 */
/** 方式二:先删除,然后在创建一个新的Job */
//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
//Class extends Job> jobClass = jobDetail.getJobClass();
//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的Job */
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务
*
*/
public static void removeJob(String uuid) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(uuid, uuid);
sched.pauseTrigger(triggerKey);// 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(JobKey.jobKey(uuid, uuid));// 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}