今天带来一个基于SpringBoot2.x整合Quartz定时器,也相当于给自己做个笔记。
项目优点:灵活插拔,接口编程,功能全面,MVC模式,方便管理
Quartz简介:
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。
使用场景:
有时候我们需要在指定时间开始自动执行一段代码,然后需要这段代码相隔指定时间执行一次,亦或者需要对Job的管理,比如增删查改,休眠,停止休眠等等,那么使用下面的代码就可以很好的解决这个问题。
看完Quartz是不是感觉Quartz很厉害有木有,下面废话不多说直接开整:
- 1:加入Pom依赖
#其他的比如Springboot的依赖各位伙伴就自己加入,对项目影响不是很大
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
- 2:创建Quartz配置类
@Configuration
public class QuartzConfig {
/**
* 注入Scheduler 任务调度者
* @return
* @throws SchedulerException
*/
@Bean(name = "createScheduler")
public Scheduler createScheduler() throws SchedulerException {
//创建任务调度工厂
SchedulerFactory sf = new StdSchedulerFactory();
//获取实例
Scheduler scheduler = sf.getScheduler();
return scheduler;
}
}
- 3:创建一个需要调用方法的Job
/**
- 需要执行的job
- 下面的注解是开启并行执行的 如果当前job没有执行完毕的时候 有新的job那么会并行执行
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class MyJob implements Job {
//执行的方法
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//获取保存参数对象
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
//得到参数 这里的参数是我们自己创建一个Job的时候封装的一个Map 具体参数可以自己定义
HashMap<String,String> param = (HashMap<String, String>) jobDataMap.get("param");
//循环查看参数 因为我这里没有调用 只是查看是否传递过来具体的业务调用根据自己项目而定
for (String str : param.keySet()){
System.err.println("key:"+str+" value:"+param.get(str));
}
//需要执行的逻辑代码
//SpringContextJobUtil .getBean(name);
}
}
- 4:封装Quartz的常规操作
@Component
public class QuartzUtils {
@Resource(name = "createScheduler")
private Scheduler scheduler;
/**
* 创建一个job的实例
* @param describe 实例的描述
* @param name 实例的名称
* @param group 实例的组名
* @param param 所需要的参数
* @return 返回lob实例
*/
private JobDetail createJobDetail(String describe, String name, String group, Map<String,String> param) {
//3.创建JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withDescription(describe) //job的描述
.withIdentity(name, group) //job 的name和group
.build();
//封装参数
jobDetail.getJobDataMap().put("param",param);
return jobDetail;
}
/**
* 触发器
* @param describe 描述
* @param name 名称
* @param group 组名
* @param startDate 开始时间
* @param cronExpression cron表达式
* @return 返回触发器
*/
private Trigger createTrigger(String describe, String name, String group, Date startDate, String cronExpression) {
//4.创建Trigger
Trigger trigger = TriggerBuilder.newTrigger()
.withDescription(describe)
.withIdentity(name, group)
//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
.startAt(startDate) //默认当前时间启动
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) //两秒执行一次
// .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
.build();
return trigger;
}
/**
* 开启Quartz定时器
* @param describe 任务描述
* @param name 任务名称
* @param group 任务组名
* @param param 需要传递的参数
* @param startData 开始的时间
* @param cronExpression cron表达式
* @throws SchedulerException 异常
*/
public void scheduleJob(String describe, String name, String group, Map<String,String> param,
Date startData, String cronExpression) throws SchedulerException {
JobDetail jobDetail = createJobDetail(describe, name, group, param);
Trigger trigger = createTrigger(describe, name, group, startData, cronExpression);
//添加到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
//开始执行
scheduler.start();
}
/**
* 获取Job信息
*
* @param name
* @param group
* @return
* @throws SchedulerException
*/
public String getJobInfo(String name, String group) throws SchedulerException {
TriggerKey triggerKey = new TriggerKey(name, group);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
scheduler.getTriggerState(triggerKey).name());
}
/**
* 修改某个任务的执行时间
*
* @param name
* @param group
* @param time
* @return
* @throws SchedulerException
*/
public boolean modifyJob(String name, String group, String time) throws SchedulerException {
Date date = null;
TriggerKey triggerKey = new TriggerKey(name, group);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
String oldTime = cronTrigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
.withSchedule(cronScheduleBuilder).build();
date = scheduler.rescheduleJob(triggerKey, trigger);
}
return date != null;
}
/**
* 暂停所有任务
*
* @throws SchedulerException
*/
public void pauseAllJob() throws SchedulerException {
scheduler.pauseAll();
}
/**
* 暂停某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void pauseJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null)
return;
scheduler.pauseJob(jobKey);
}
/**
* 恢复所有任务
*
* @throws SchedulerException
*/
public void resumeAllJob() throws SchedulerException {
scheduler.resumeAll();
}
/**
* 恢复某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void resumeJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null)
return;
scheduler.resumeJob(jobKey);
}
/**
* 删除某个任务
*
* @param name
* @param group
* @throws SchedulerException
*/
public void deleteJob(String name, String group) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null)
return;
scheduler.deleteJob(jobKey);
}
}
- 5:封装一个controller控制层
@RestController
@RequestMapping(value = "/quartz")
public class QuartzController extends BaseApiService {
@Autowired
private QuartzUtils quartzUtils;
/**
* 新增一个job
* @param quartzControllerParam 参数
* @return 统一格式
* @throws SchedulerException 异常
*/
@RequestMapping(value = "/createTicketGrabbingJob")
public ResponseBase createTicketGrabbingJob(@RequestBody QuartzControllerParam quartzControllerParam) throws SchedulerException {
// String cronExpression = "0/2 * * * * ?";
quartzUtils.scheduleJob(quartzControllerParam.getDescribe(), quartzControllerParam.getName()
, quartzControllerParam.getGroup(), quartzControllerParam.getParam(), quartzControllerParam.getStartData()
, quartzControllerParam.getCronExpression());
return setResultSuccessData(quartzControllerParam,"设置定时任务成功");
}
/**
* 查询job信息
*
* @param quartzControllerParam 参数
* @return 返回结果
* @throws SchedulerException Quartz错误
*/
@RequestMapping(value = "/getJobInfo")
public ResponseBase getJobInfo(@RequestBody QuartzControllerParam quartzControllerParam) throws SchedulerException {
String jobInfo = quartzUtils.getJobInfo(quartzControllerParam.getName(), quartzControllerParam.getGroup());
return setResultSuccessData("查询Job信息成功", jobInfo);
}
/**
* 停止单个job
*
* @param quartzControllerParam 参数
* @return 返回结果
* @throws SchedulerException Quartz错误
*/
@RequestMapping(value = "/pauseOneJob")
public ResponseBase pauseOneJob(@RequestBody QuartzControllerParam quartzControllerParam) throws SchedulerException {
quartzUtils.pauseJob(quartzControllerParam.getName(), quartzControllerParam.getGroup());
return setResultSuccess("成功停止 " + quartzControllerParam.getName() + " job");
}
/**
* 恢复单个job
*
* @param quartzControllerParam 参数
* @return 返回结果
* @throws SchedulerException Quartz错误
*/
@RequestMapping(value = "/resumeOneJob")
public ResponseBase resumeOneJob(@RequestBody QuartzControllerParam quartzControllerParam) throws SchedulerException {
quartzUtils.resumeJob(quartzControllerParam.getName(), quartzControllerParam.getGroup());
return setResultSuccess("成功恢复 "+quartzControllerParam.getName()+" Job");
}
/**
* 删除单个job
*
* @param quartzControllerParam job名称
* @return 返回结果
* @throws SchedulerException Quartz错误
*/
@RequestMapping(value = "/deleteOneJob")
public ResponseBase deleteOneJob(@RequestBody QuartzControllerParam quartzControllerParam) throws SchedulerException {
quartzUtils.deleteJob(quartzControllerParam.getName(), quartzControllerParam.getGroup());
return setResultSuccess("删除 " + quartzControllerParam.getName() + " Job成功");
}
}
- 6:创建一个获取javaBean的类
@Component
public class SpringContextJobUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
@SuppressWarnings("static-access" )
public void setApplicationContext(ApplicationContext contex)
throws BeansException {
// TODO Auto-generated method stub
this.context = contex;
}
public static Object getBean(String beanName){
return context.getBean(beanName);
}
public static String getMessage(String key){
return context.getMessage(key, null, Locale.getDefault());
}
}
更新:由于在job中无法使用@Autowired进行注入依赖,所以我们需要创建一个工具类SpringContextJobUtil进行获取Bean。
Job中无法使用@Autowired进行注入依赖参考解决:https://www.jianshu.com/p/aff9199b4416
总结:自此单机版本的Quzrtz就封装完毕了,各位朋友们致以直接复制代码直接使用,所有接口都经过测试,没有bug,希望可以帮到大家,另外有不足的地方也请大家指出。