文章目录
- Spring Boot Quartz 实现动态创建
- 需求
- 技术简介
- 主要源代码
- 应用启动,初始化定时器并入库
- 编写Controller,调用Quartz 增、删、改、查方法
- Quartz核心工具类[QuartzManager]
- ServiceImpl
Spring Boot Quartz 实现动态创建
需求
- 应用启动时,初始化定时器
- 可查询正在运行的定时器
- 可修改正在运行的定时器
- 可触发立即执行定时器
- 将定时任务入库
技术简介
- Spring Boot 2.0.3 基础框架
- Quartz 操作队列
主要源代码
应用启动,初始化定时器并入库
@Component
public class StartRunner implements CommandLineRunner {
private static final Log logger = LogFactory.getLog(StartRunner.class);
private static final String JOB_INIT_INI_JOB = "com.sb.quartz.job.JobInit";
private static final String JOB_INIT_CRON_EXP = "*/5 * * * * ?";
@Autowired
QuartzManager quartzManager;
@Autowired
JobService jobService;
@Override
public void run(String... args) {
logger.info("定时任务初始化 ———————— begin");
if(quartzManager.addJob(Constants.JOB_INIT_INIT_JOB, JOB_INIT_INI_JOB, JOB_INIT_CRON_EXP)) {
logger.info("["+ Constants.JOB_INIT_INIT_JOB + "]" + "定时任务初始化成功!");
} else {
logger.info("["+ Constants.JOB_INIT_INIT_JOB + "]" + "定时任务初始化失败!");
}
logger.info("定时任务初始化 ———————— end");
}
}
编写Controller,调用Quartz 增、删、改、查方法
@RestController
public class JobController {
private static final String JOB_INIT_INI_JOB = "com.sb.quartz.job.JobInit";
private static final String JOB_INIT_CRON_EXP = "*/5 * * * * ?";
@Autowired
QuartzManager quartzManager;
@RequestMapping(value = "/initJob", method = RequestMethod.GET)
public ResultUtil initJob() {
if(quartzManager.addJob(Constants.JOB_INIT_INIT_JOB, JOB_INIT_INI_JOB, JOB_INIT_CRON_EXP)) {
return new ResultUtil.Builder<>().success("初始化任务成功").build();
} else {
return new ResultUtil.Builder<>().failure("初始化任务失败").build();
}
}
@RequestMapping(value = "/deleteJob" , method = RequestMethod.GET)
public ResultUtil deleteJob(@RequestParam("jobName") String jobName) {
if(quartzManager.deleteJob(jobName)) {
return new ResultUtil.Builder<>().success("删除任务成功").build();
} else {
return new ResultUtil.Builder<>().failure("删除任务失败").build();
}
}
@RequestMapping(value = "/updateJob", method = RequestMethod.GET)
public ResultUtil updateJob(String jobName, String exp) {
if(quartzManager.updateJob(jobName, exp)) {
return new ResultUtil.Builder<>().success("修改任务成功").build();
} else {
return new ResultUtil.Builder<>().failure("修改任务失败").build();
}
}
@RequestMapping(value = "/triggerJob", method = RequestMethod.GET)
public ResultUtil triggerJob(String jobName) {
if(quartzManager.triggerJob(jobName)) {
return new ResultUtil.Builder<>().success("任务触发成功").build();
} else {
return new ResultUtil.Builder<>().failure("任务触发失败").build();
}
}
@RequestMapping(value = "/findJobs", method = RequestMethod.GET)
public ResultUtil findJobs() {
List<JobVO> jobVOList = quartzManager.findJobs();
if(jobVOList.size() > 0 ) {
return new ResultUtil.Builder<>().success(jobVOList).build();
} else {
return new ResultUtil.Builder<>().failure("没有正在执行的任务").build();
}
}
}
Quartz核心工具类[QuartzManager]
@Component
@Scope("singleton")
public class QuartzManager implements ApplicationContextAware {
private static final Log logger = LogFactory.getLog(QuartzManager.class);
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
private ApplicationContext applicationContext;
@Autowired
private Scheduler scheduler;
@Autowired
private AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory;
public void start() {
try {
this.scheduler = schedulerFactory.getScheduler();
scheduler.setJobFactory(autowiringSpringBeanJobFactory);
Map<String, AbstractTask> tasks = applicationContext.getBeansOfType(AbstractTask.class);
tasks.forEach((k, v) -> {
String cronExpression = v.getCronExpression();
if (cronExpression != null) {
addJob(k, v.getClass().getName(), cronExpression);
}
});
logger.info("start jobs finished.");
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException("init Scheduler failed");
}
}
public boolean addJob(String jobName, String jobClass, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
logger.error("Illegal cron expression format({})" + cronExp);
return result;
}
try {
JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, Constants.JOB_DEFAULT_GROUP_NAME))
.ofType((Class<Job>) Class.forName(jobClass))
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, Constants.TRIGGER_DEFAULT_GROUP_NAME))
.build();
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
result = true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("QuartzManager add job failed");
}
return result;
}
public boolean updateJob(String jobName, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
logger.error("Illegal cron expression format({})" + cronExp);
return result;
}
JobKey jobKey = new JobKey(jobName, Constants.JOB_DEFAULT_GROUP_NAME);
TriggerKey triggerKey = new TriggerKey(jobName, Constants.TRIGGER_DEFAULT_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, Constants.TRIGGER_DEFAULT_GROUP_NAME))
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
result = true;
} else {
logger.error("update job name:{},group name:{} or trigger name:{},group name:{} not exists.." +
jobKey.getName() + jobKey.getGroup() + triggerKey.getName() + triggerKey.getGroup());
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
logger.error("update job name:{},group name:{} failed!" + jobKey.getName() + jobKey.getGroup());
}
return result;
}
public boolean deleteJob(String jobName) {
boolean result = false;
JobKey jobKey = new JobKey(jobName, Constants.JOB_DEFAULT_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey)) {
result = scheduler.deleteJob(jobKey);
} else {
logger.error("delete job name:{},group name:{} not exists." + jobKey.getName() + jobKey.getGroup());
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
logger.error("delete job name:{},group name:{} failed!" + jobKey.getName() + jobKey.getGroup());
}
return result;
}
public boolean triggerJob(String jobName) {
boolean result = false;
JobKey jobKey = new JobKey(jobName, Constants.JOB_DEFAULT_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey)) {
scheduler.triggerJob(jobKey);
result = true;
} else {
logger.error("job not found —— " + jobName);
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
logger.error("trigger job name:{},group name:{} failed!" + jobKey.getName() + jobKey.getGroup());
}
return result;
}
public List<JobVO> findJobs() {
List<JobVO> jobVOList = new ArrayList<>();
try {
for (String groupName : scheduler.getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
JobVO jobVO = new JobVO();
jobVO.setJobName(jobKey.getName());
jobVO.setJobGroup(jobKey.getGroup());
List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
Date nextFireTime = triggers.get(0).getNextFireTime();
jobVO.setJobNextTime(DateUtil.dateToString(nextFireTime));
jobVOList.add(jobVO);
System.out.println("[jobName] : " + jobKey.getName() + " [groupName] : "
+ jobKey.getGroup() + " - " + nextFireTime);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return jobVOList;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
ServiceImpl
@Service
public class JobServiceImpl implements JobService {
private static final Log logger = LogFactory.getLog(JobServiceImpl.class);
@Autowired
private JobMainMapper jobMainMapper;
@Autowired
private JobDetailMapper jobDetailMapper;
@Override
public void testTask() {
System.out.println(new Date() + "设置了一个定时任务1,5s/次频率");
}
@Override
public void testTask2() {
System.out.println(new Date() + "设置了一个定时任务2,5s/次频率");
}
}