专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

springboot quartz 手写任务调度

添加引用


<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>

QuartzFactory类:主要用于解决springboot quartz job 无法注入bean的问题。


package com.example.springboot; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; import org.springframework.stereotype.Component; @Component public class QuartzFactory extends AdaptableJobFactory { /** * AutowireCapableBeanFactory接口是BeanFactory的子类 * 可以连接和填充那些生命周期不被Spring管理的已存在的bean实例 */ private AutowireCapableBeanFactory factory; public QuartzFactory(AutowireCapableBeanFactory factory) { this.factory = factory; } /** * 创建Job实例 */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // 实例化对象 Object job = super.createJobInstance(bundle); // 进行注入(Spring管理该Bean) factory.autowireBean(job); //返回对象 return job; } }

QuartzConfig类:主要用于解决springboot quartz job 无法注入bean的问题,需要配合QuartzFactory类。


package com.example.springboot; import org.quartz.Scheduler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.SchedulerFactoryBean; @Configuration public class QuartzConfig { private QuartzFactory quartzFactory; public QuartzConfig(QuartzFactory quartzFactory) { this.quartzFactory = quartzFactory; } /** * 配置SchedulerFactoryBean * 将一个方法产生为Bean并交给Spring容器管理 */ @Bean public SchedulerFactoryBean schedulerFactoryBean() { // Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期 SchedulerFactoryBean factory = new SchedulerFactoryBean(); // 设置自定义Job Factory,用于Spring管理Job bean factory.setJobFactory(quartzFactory); return factory; } @Bean(name = "scheduler") public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); } }

QuartzService类:封装一些任务调度的东西,主要也用于测试注入job的bean对象。


package com.example.springboot; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.Date; @Slf4j @Service public class QuartzService { @Autowired private Scheduler scheduler; // 添加调度任务 public Boolean addScheduler(Integer id, String cron) throws Exception { // 判断,如果因为意外将过期调度任务传递过来,进行排除 // ... // 添加一个去重复的操作 if (scheduler.getJobDetail(JobKey.jobKey(id.toString())) != null) { return Boolean.TRUE; } // 构建一个job JobDetail jobDetail = JobBuilder .newJob(QuartzJob.class) .withIdentity(id.toString()) .usingJobData("param", id.toString()) .build(); // 构建一个trigger CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(id.toString()) .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); // 构建一个scheduler Date nextExecuteTime = scheduler.scheduleJob(jobDetail, trigger); //开始执行 scheduler.start(); return Boolean.TRUE; } // 取消调度任务,并且清除缓存 public Boolean deleteJob(Integer id) { Boolean result = Boolean.FALSE; try { // 删除job result = scheduler.deleteJob(JobKey.jobKey(id.toString())); } catch (Exception ex) { // 记录个日志 log.error(String.format("%s-删除调度器出现异常:%s,堆栈信息:%s", id, ex.getMessage(), ExceptionUtils.getStackTrace(ex))); } return result; } // 查询调度任务 public Boolean query(Integer id) throws Exception { JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(id.toString())); if (jobDetail == null) { return Boolean.FALSE; } else { return Boolean.TRUE; } } // 得到cron的下一次执行时间 public String getNextExecuteTime(String cron) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 验证cron的正确性 System.out.println(CronExpression.isValidExpression(cron)); if (CronExpression.isValidExpression(cron)) { CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity("default") .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); // 获取到下一次执行时间 Date nextTime = trigger.getFireTimeAfter(trigger.getStartTime()); return df.format(nextTime); } else { return "表达式不合法"; } } }

QuartzJob类:就是job要执行的类,该类如果不做特殊处理,是无法将bean对象注入该类的。重点就是QuartzFactory和QuartzConfig两个类的添加,没有什么需要特别注意的东西。


package com.example.springboot; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Slf4j @Component public class QuartzJob implements Job { // 正常情况下,这里是注入不进来的,故意写个来检验注入bean问题 @Autowired private QuartzService quartzService; @Override public void execute(JobExecutionContext context) throws JobExecutionException { try { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); // 获取参数 String param = jobDataMap.getString("param"); System.out.println(param + "——开始执行"); Thread.sleep(1000); // 调用删除调度器的方法 Boolean result = quartzService.deleteJob(Integer.valueOf(param)); System.out.println(param + "——执行结束,取消调度任务结果:" + result); } catch (Exception ex) { log.error(String.format("执行调度器出现异常:%s,堆栈信息:%s", ex.getMessage(), ExceptionUtils.getStackTrace(ex))); } } }

QuartzController类:测试类,用于调用任务的添加,删除和查询。


package com.example.springboot; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class QuartzController { @Autowired private QuartzService quartzService; @RequestMapping("/quartz/add/{id}") private Boolean index(@PathVariable Integer id, @RequestBody String cron) throws Exception { Boolean result = quartzService.addScheduler(id, cron); return result; } @RequestMapping("/quartz/delete/{id}") public Boolean cancel(@PathVariable Integer id) { Boolean result = quartzService.deleteJob(id); return result; } @RequestMapping("/quartz/query/{id}") public Boolean query(@PathVariable Integer id) throws Exception { Boolean result = quartzService.query(id); return result; } }

注意:由于job类无法注入spring bean对象,因此需要添加QuartzFactory和QuartzConfig两个类,然后Scheduler调用方式,不是采用new,而是注入的方式,参见QuartzService中的Scheduler使用。

吐槽一下,网上代码都是各种copy,找点有用的找不到。就想找为什么job类无法注入,解决方案都找半天没有用,后来自己总结搞了下,其实就是添加两个类就可以了,很简单,非得贴一大坨代码,也没有说明解释。springboot quartz无法注入问题参见上述红字把。

未经允许不得转载:搜云库技术团队 » springboot quartz 手写任务调度

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们