这篇文章将为大家详细讲解有关如何在springboot项目中实现一个动态定时任务,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
1、maven引入quartz包
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency>
2、创建定时任务工厂类
/** * 定时任务工厂类 */ @Component public class JobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { final Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.beanFactory = applicationContext.getAutowireCapableBeanFactory(); } }
3、创建定时任务抽象类
public abstract class AbstractTask implements Job { private Logger logger = LoggerFactory.getLogger(AbstractTask.class); protected abstract void executeInternal(JobExecutionContext context) throws Exception; /** * 定时任务标识 */ private String key; /** * 数据库里配置的主键id */ private Long dataBaseId; @Override public void execute(JobExecutionContext context) { try { executeInternal(context); } catch (Exception e) { logger.error(e.getMessage(), e); logger.error("job execute failed!"); } } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Long getDataBaseId() { return dataBaseId; } public void setDataBaseId(Long dataBaseId) { this.dataBaseId = dataBaseId; } }
4、创建定时任务业务实现类
这里可以写你的业务代码,实现具体的业务逻辑。
@Component("JobTask") public class JobTask extends AbstractTask { @Override protected void executeInternal(JobExecutionContext context) { System.out.println("key = " + this.getKey()); System.out.println("dataBaseId = " + this.getDataBaseId()); } }
5、创建定时任务管理器
包括项目启动时添加定时任务,手动添加定时任务,更新定时任务,删除定时任务方法。
/** * 定时任务管理容器 component (单例模式) */ @Component @Scope("singleton") public class JobQuartzManager implements ApplicationContextAware { /** * 创建新的scheduler */ private static SchedulerFactory schedulerFactory = new StdSchedulerFactory(); private Scheduler scheduler; /** * 定义组名称,不同的组用于区分任务 */ private static final String JOB_GROUP_NAME = "JOB_GROUP_NAME"; private static final String TRIGGER_GROUP_NAME = "TRIGGER_GROUP_NAME"; /** * 日志 */ private Logger logger = LoggerFactory.getLogger(JobQuartzManager.class); private ApplicationContext applicationContext; @Autowired private JobFactory jobFactory; public void start() { //启动定时任务(初始化) try { this.scheduler = schedulerFactory.getScheduler(); scheduler.setJobFactory(jobFactory); //设置定时任务工厂模式 //项目启动时默认给spring容器添加动态的定时任务 this.addJob("job" + 100L, 100L, JobTask.class, "0/2 * * * * ?"); } catch (SchedulerException e) { logger.error(e.getMessage(), e); throw new RuntimeException("init Scheduler failed"); } } public boolean addJob(String jobName, Long dataBaseId, Class 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, JOB_GROUP_NAME)) .ofType((Class<AbstractTask>) Class.forName(jobClass.getName())) .build(); //创建完jobDetail之后,使用语句传参数值,方便定时任务内部识别它是什么标识 JobDataMap jobDataMap = jobDetail.getJobDataMap(); jobDataMap.put("key", jobName); jobDataMap.put("dataBaseId", dataBaseId); Trigger trigger = TriggerBuilder.newTrigger() .forJob(jobDetail) .withSchedule(CronScheduleBuilder.cronSchedule(cronExp)) .withIdentity(new TriggerKey(jobName, TRIGGER_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, JOB_GROUP_NAME); TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_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, TRIGGER_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, JOB_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; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
6、创建定时任务启动类
项目运行时给spring注入定时任务
/** * 定时任务启动类 */ @Component public class JobRunner implements ApplicationRunner { //注入定时任务管理器 @Autowired private JobQuartzManager quartzManager; /** * 项目启动时激活定时任务 */ @Override public void run(ApplicationArguments applicationArguments) { System.out.println("--------------------注入定时任务---------------------"); quartzManager.start(); System.out.println("--------------------定时任务注入完成---------------------"); } }
7、测试案例
@RestController @RequestMapping("/job") public class JobController { @Autowired JobQuartzManager quartzManager; @PostMapping("addJob") @ResponseBody public String addJob(@RequestParam("dataBaseId") Long dataBaseId, @RequestParam("cronExp") String cronExp){ boolean success = quartzManager.addJob("job" + dataBaseId, dataBaseId, JobTask.class, cronExp); if(success){ return "添加成功"; }else{ return "添加失败!"; } } @PostMapping("deleteJob") @ResponseBody public String deleteJob(@RequestParam("jobName") String jobName){ boolean success = quartzManager.deleteJob(jobName); if(success){ return "删除成功"; }else{ return "删除失败!"; } } @PostMapping("updateJob") @ResponseBody public String updateJob(@RequestParam("jobName") String jobName, @RequestParam("cronExp") String cronExp){ boolean success = quartzManager.updateJob(jobName, cronExp); if(success){ return "更新成功"; }else{ return "更新失败!"; } } }
关于如何在springboot项目中实现一个动态定时任务就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。