SpringBoot整合Quertz定时器
Maven依赖:
1 2 3 4 5 6 7 8 9 | <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version> 2.2 . 1 </version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> |
Quertz数据表(MySQL):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | CREATE TABLE `sys_task` ( `id` bigint( 20 ) NOT NULL AUTO_INCREMENT, `job_name` varchar( 255 ) DEFAULT NULL COMMENT '任务名' , `description` varchar( 255 ) DEFAULT NULL COMMENT '任务描述' , `cron_expression` varchar( 255 ) DEFAULT NULL COMMENT 'cron表达式' , `bean_class` varchar( 255 ) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名' , `job_status` varchar( 255 ) DEFAULT NULL COMMENT '任务状态' , 0 :停止 1 :运行, `job_group` varchar( 255 ) DEFAULT NULL COMMENT '任务分组' , `create_user` varchar( 64 ) DEFAULT NULL COMMENT '创建者' , `create_time` datetime DEFAULT NULL COMMENT '创建时间' , `update_user` varchar( 64 ) DEFAULT NULL COMMENT '更新者' , `update_time` datetime DEFAULT NULL COMMENT '更新时间' , PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT= 32 DEFAULT CHARSET=utf8;<br><br>INSERT INTO `sys_task` VALUES ( '1' , 'QuertzTask1' , 'Quertz定时器测试一' , '0/10 * * * * ?' , 'com.example.demo.Quertz.TestQuertzTask' , '1' , 'group' , null , null , null , null ); |
Quertz配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.example.demo.Quertz; import org.quartz.Scheduler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import java.io.IOException; import java.util.Properties; @Configuration public class QuartzConfigration { @Autowired private JobFactory jobFactory; @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); try { schedulerFactoryBean.setOverwriteExistingJobs( true ); schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setJobFactory(jobFactory); } catch (Exception e) { e.printStackTrace(); } return schedulerFactoryBean; } // 指定quartz.properties,可在配置文件中配置相关属性 @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation( new ClassPathResource( "/config/quartz.properties" )); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } // 创建schedule @Bean (name = "scheduler" ) public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.example.demo.Quertz; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; import org.springframework.stereotype.Component; @Component public class JobFactory extends AdaptableJobFactory { //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴. //为什么需要这个类呢,在我写的这个demo中,大家可以将此类删掉,发现程序也可以政策运营,可是我为什么还是加上呢。 //大家可以看下我们的任务类,大家可以看到Job对象的实例化过程是在Quartz中进行的,这时候我们将spring的东西注入进来,肯定是行不通的,所以需要这个类 @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法 Object jobInstance = super .createJobInstance(bundle); //进行注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } } |
SpringBoot启动加载定时器任务(实现接口 CommandLineRunner 来实现):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.example.demo.Quertz; import com.example.demo.Entity.Task; import com.example.demo.Service.QuertzTaskService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.List; @Component @Order (value = 1 ) public class QuartzTask implements CommandLineRunner { @Autowired private QuertzTaskService quertzTaskService; @Autowired private QuertzManage quertzManage; @Override public void run(String... arg0) throws Exception { List<Task> taskList = quertzTaskService.queryQuertzTask(); for (Task task : taskList) { quertzManage.addJob(task); } } } |
Quertz定时器启动,暂停,运行等封装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | package com.example.demo.Quertz; import com.example.demo.Entity.Task; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class QuertzManage { @Autowired private Scheduler scheduler; /** * 添加一个job * @param task */ public void addJob(Task task) { try { // 创建jobDetail实例,绑定Job实现类 // 指明job的名称,所在组的名称,以及绑定job类 Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(task.getBeanClass()).newInstance() .getClass()); JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(task.getJobName(), task.getJobGroup()) // 任务名称和组构成任务key .build(); // 定义调度触发规则 // 使用cornTrigger规则 Trigger trigger = TriggerBuilder.newTrigger().withIdentity(task.getJobName(), task.getJobGroup()) // 触发器key .startAt(DateBuilder.futureDate( 1 , DateBuilder.IntervalUnit.SECOND)) .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression())).startNow().build(); // 把作业和触发器注册到任务调度中 scheduler.scheduleJob(jobDetail, trigger); // 启动 if (!scheduler.isShutdown()) { scheduler.start(); } } catch (Exception e) { e.printStackTrace(); } } /** * 暂停一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void pauseJob(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.pauseJob(jobKey); } /** * 恢复一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void resumeJob(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.resumeJob(jobKey); } /** * 立即执行一个job * @param jobName * @param jobGroup * @throws SchedulerException */ public void runJobNow(String jobName,String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); scheduler.triggerJob(jobKey); } } |
SpringDataJPA查询接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package com.example.demo.Service; import com.example.demo.Entity.Task; import org.quartz.SchedulerException; import java.util.List; public interface QuertzTaskService { List<Task> queryQuertzTask(); void pauseTaskById(String id) throws SchedulerException; void resumeTaskById(String id) throws SchedulerException; } |
接口实现方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package com.example.demo.Service.Impl; import com.example.demo.Entity.Task; import com.example.demo.Quertz.QuertzManage; import com.example.demo.Repository.TaskRepository; import com.example.demo.Service.QuertzTaskService; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class QuertzTaskServiceImpl implements QuertzTaskService { @Autowired private TaskRepository taskRepository; @Autowired private QuertzManage quertzManage; @Override public List<Task> queryQuertzTask() { return taskRepository.findByJobStatus(); } @Override public void pauseTaskById(String id) throws SchedulerException { Optional<Task> task = taskRepository.findById(id); quertzManage.pauseJob(task.get().getJobName(),task.get().getJobGroup()); } @Override public void resumeTaskById(String id) throws SchedulerException { Optional<Task> task = taskRepository.findById(id); quertzManage.resumeJob(task.get().getJobName(),task.get().getJobGroup()); } } |
定时任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package com.example.demo.Quertz; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @DisallowConcurrentExecution //作业不并发 @Component public class TestQuertzTask implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); System.out.println( "Quertz定时器: " +dateFormat.format( new Date())); } } |
源码:https://github.com/zeng-xian-guo/springboot_jwt_token.git
参考:https://blog.csdn.net/qq_40065776/article/details/107489728
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类