springboot整合定时任务quartz
1、定时任务的的相关方法:
package org.springeos.modules.quartz.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springeos.core.tool.api.R;
import org.springeos.modules.quartz.mapper.QuartzMapper;
import org.springeos.modules.quartz.service.QuartzService;
import org.springeos.modules.quartz.vo.QuartzVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class QuartzServiceImpl implements QuartzService {
@Autowired
private Scheduler scheduler;
@Autowired
private QuartzMapper quartzMapper;
@Override
public R addJob(String jobClassName, String jobName, String groupName, String cronExpression) {
R<Object> r = new R<>();
try {
//构建job信息
JobDetail jobDetail =
JobBuilder.newJob((Class<? extends Job>)Class.forName(jobClassName))
.withIdentity(jobName, groupName)
.build();
//表达式调度构建器(即任务执行的时间)
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName)
.startNow().withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
// 启动调度器
scheduler.start();
log.info("创建定时任务成功!");
r.setSuccess(true);
r.setMsg("创建定时任务成功!");
} catch (SchedulerException | ClassNotFoundException e) {
log.error("创建定时任务失败"+e);
r.setMsg("创建定时任务失败!");
r.setSuccess(false);
}finally {
return r;
}
}
@Override
public R pauseJob(String jobName, String jobGroupName) {
R<Object> r = new R<>();
try {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroupName));
log.info("暂停定时任务成功!");
r.setSuccess(true);
r.setMsg("暂停定时任务成功!");
} catch (SchedulerException e) {
log.error("暂停定时任务失败"+e);
e.printStackTrace();
r.setSuccess(false);
r.setMsg("暂停定时任务失败!");
}finally {
return r;
}
}
@Override
public R resumeJob(String jobName, String jobGroupName) {
R<Object> r = new R<>();
try {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroupName));
r.setSuccess(true);
r.setMsg("恢复定时任务成功!");
} catch (SchedulerException e) {
log.error("恢复定时任务失败"+e);
e.printStackTrace();
r.setSuccess(true);
r.setMsg("恢复定时任务失败!");
}finally {
return r;
}
}
@Override
public R rescheduleJob(String jobName, String triggerGroupName, String cronExpression) {
R<Object> r = new R<>();
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
r.setSuccess(true);
r.setMsg("更新定时任务成功!");;
} catch (SchedulerException e) {
log.error("更新定时任务失败"+e);
r.setSuccess(true);
r.setMsg("更新定时任务失败!");
}finally {
return r;
}
}
@Override
public R deleteJob(String jobName, String jobGroupName) {
R<Object> r = new R<>();
try {
scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
r.setSuccess(true);
r.setMsg("删除定时任务成功!");
} catch (SchedulerException e) {
log.error("删除定时任务失败"+e);
e.printStackTrace();
r.setSuccess(true);
r.setMsg("删除定时任务失败!");
}finally {
return r;
}
}
@Override
public boolean checkExists(String jobName, String jobGroupName) {
try {
JobDetail jobDetail = scheduler.getJobDetail(new JobKey(jobName, jobGroupName));
return jobDetail!=null;
} catch (SchedulerException e) {
log.error("根据jobName和groupName检查job是否存在失败"+e);
e.printStackTrace();
}
return false;
}
@Override
public IPage<QuartzVO> pageJob(Page page) {
List<QuartzVO> pageJob = quartzMapper.pageJob(page);
return page.setRecords(pageJob);
}
}
2、需要的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
3、配置文件:
表11张,第一次启动的时候配置initialize-schema: never会自动生成表,然后改成never即可,否则后续还会初始化表,删掉原来的数据
表:
#数据源配置
spring:
# redis:
# ##redis 单机环境配置
# host: xxx
# port: 6379
# password: xxx
# database: 0
# ssl: false
datasource:
# Oracle
url: xxx
username: xx
password: xx
quartz:
jdbc:
# 初始化Quartz表结构,项目第一次启动配置程always,然后改成never 否则已生成的job会被初始化掉
initialize-schema: never
# 作业存储类型
job-store-type: jdbc
# 调度程序的名称
scheduler-name: hrCleanScheduler
properties:
org:
quartz:
scheduler:
instanceName: etlCleanScheduler
instanceId: AUTO
jobStore:
#数据保存方式为持久化
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#Quartz表前缀
tablePrefix: QRTZ_
#是否加入集群
isClustered: false
clusterCheckinInterval: 10000
useProperties: false
# 调度器线程池配置
threadPool:
class: org.quartz.simpl.SimpleThreadPool
#线程数
threadCount: 20
#线程优先级
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
4、自己写一个controller,service来方便接口调用,,自己写的分页方法,
controller:
package org.springeos.modules.quartz.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springeos.core.launch.constant.AppConstant;
import org.springeos.core.tool.api.R;
import org.springeos.modules.quartz.service.QuartzService;
import org.springeos.modules.quartz.vo.QuartzVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 关于job的管理
*
* @author wangk
* @date 2019-08-13
*/
@Slf4j
@Api(value = "关于job的管理接口",tags = "定时任务接口")
@RestController
@RequestMapping(value = AppConstant.APPLICATION_SYSTEM_NAME+"/job")
public class QuartzController{
@Autowired
private QuartzService jobService;
@PostMapping(value = "/addJob")
@ApiOperation(value = "添加job",notes = "jobClassName请使用类的全路径名" )
public R addJob(
@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobName") String jobName,
@RequestParam(value = "jobGroupName") String jobGroupName,
@RequestParam(value = "cronExpression") String cronExpression) {
log.info("添加job---jobName:"+jobName+"---jobGroupName:"+jobGroupName);
return jobService.addJob(jobClassName, jobName, jobGroupName, cronExpression);
}
@PostMapping(value="/pauseJob")
@ApiOperation(value = "暂停job")
public R pauseJob(
@RequestParam(value="jobName")String jobName,
@RequestParam(value="jobGroupName")String jobGroupName){
log.info("暂停job---jobName:"+jobName+"---jobGroupName:"+jobGroupName);
return jobService.pauseJob(jobName, jobGroupName);
}
@PostMapping(value="/resumeJob")
@ApiOperation(value = "恢复job")
public R resumeJob(
@RequestParam(value="jobName")String jobName,
@RequestParam(value="jobGroupName")String jobGroupName){
log.info("恢复job---jobName:"+jobName+"---jobGroupName:"+jobGroupName);
return jobService.resumeJob(jobName, jobGroupName);
}
@PostMapping(value="/rescheduleJob")
@ApiOperation(value = "更新job")
public R rescheduleJob(
@RequestParam(value="jobName")String jobName,
@RequestParam(value="triggerGroupName")String triggerGroupName,
@RequestParam(value="cronExpression")String cronExpression){
log.info("更新job---jobName:"+jobName);
return jobService.rescheduleJob(jobName, triggerGroupName,cronExpression);
}
@PostMapping(value = "/deleteJob")
@ApiOperation(value = "删除job")
public R deleteJob(
@RequestParam(value = "jobName") String jobName,
@RequestParam(value = "jobGroupName") String jobGroupName) {
log.info("删除job---jobName:"+jobName+"---jobGroupName:"+jobGroupName);
return jobService.deleteJob(jobName, jobGroupName);
}
//分页查询
@PostMapping("/page")
@ApiOperation(value = "分页查询")
public R<IPage<QuartzVO>> pageJob(Page page) {
log.info("分页查询");
IPage<QuartzVO> result = jobService.pageJob(page);
return R.data(result);
}
}
service:
package org.springeos.modules.quartz.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springeos.core.tool.api.R;
import org.springeos.modules.quartz.vo.QuartzVO;
public interface QuartzService{
R addJob(String jobClassName, String jobName, String groupName, String cronExpression);
R pauseJob(String jobName, String jobGroupName);
R resumeJob(String jobName, String jobGroupName);
R rescheduleJob(String jobName, String triggerGroupName, String cronExpression);
R deleteJob(String jobName, String jobGroupName);
boolean checkExists(String jobName, String jobGroupName);
IPage<QuartzVO> pageJob(Page page);
}
mapper:
package org.springeos.modules.quartz.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Select;
import org.springeos.modules.quartz.vo.QuartzVO;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface QuartzMapper extends BaseMapper<QuartzVO> {
@Select("SELECT DISTINCT j.JOB_NAME AS jobName, j.JOB_GROUP AS jobGroupName, j.JOB_CLASS_NAME AS jobClassName, c.CRON_EXPRESSION AS cronExpression, q.TRIGGER_STATE AS triggerState, q.TRIGGER_NAME AS triggerName, q.TRIGGER_GROUP AS triggerGroup FROM QRTZ_JOB_DETAILS j INNER JOIN QRTZ_CRON_TRIGGERS c ON j.JOB_NAME = c.TRIGGER_NAME INNER JOIN QRTZ_TRIGGERS q ON j.JOB_NAME = q.JOB_NAME")
List<QuartzVO> pageJob(Page page);
}
5、测试job:
package org.springeos.modules.quartz.job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class HelloJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.err.println("定时任务正在执行----------------------------------");
}
}
postman调用新增定时任务的接口:
任务名和组名可以任意写,配置好任务类所在的路径和定时表达式,访问即可
http://localhost:80/eos-system/job/addJob
通过控制台发现定时任务可发现定时任务可以正常执行
去表中查看,QRTZ_JOB_DETAILS表中已经插入数据
corn触发器表中也正常插入数据