SpringBoot如何整合Quartz 雨点打透心脏的1/2处 2024-03-22 09:18 11阅读 0赞 ### 基础依赖 ### <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> <version>2.5.2</version> </dependency> 复制代码 Quartz是**单应用工程**中用的比较多的定时任务框架。该定时任务主要可以分为: 1. **在内存中的任务**:一般定义在工程内部存储,如果工程重启后,若该任务非自动执行的,则不会再开启。 2. **可持久化的任务**:将任务的特性存储在数据库中,工程重启后可以重新读取原先正在执行的任务,继续执行。 ### cron表达式 ### `corn`是用来控制任务触发的时刻。 我列举一些常用的: * 每秒钟触发 "* * * * * *": 复制代码 * 每隔5秒执行一次 */5 * * * * ? 复制代码 * 每分钟触发 "0 * * * * ?" 复制代码 * 每一小时触发 "0 * * * * ?" 复制代码 * 每天10点触发一次 "0 0 10 * * ?" 复制代码 * 每天0点触发一次 "0 0 0 * * ?" 复制代码 ### 通用 ### 需要在启动类上加上`@EnableScheduling`注解。 ### 内存任务 ### #### 工程启动时就在执行的任务 #### 直接定义一个执行任务,例如: 每秒都输出`测试` @Service public class ScheduleTest { @Scheduled(cron = "0/1 * * * * *") public void test() { System.out.println("测试"); } } 复制代码 启动类: @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 复制代码 启动后看控制台中就会输出相应的内容。 #### 手动控制某个任务 #### 这里需要我们自己定义任务。 定义任务 通过实现`Job`接口,即可定义一个任务,并且我们可以手动去控制这个任务的开启。 public class SimpleJob implements Job { @Override public void execute(JobExecutionContext context) { System.out.println("自定义任务"); } } 复制代码 借助Web-Controller去开启该任务 导入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.6.RELEASE</version> </dependency> 复制代码 编写Controller,这是一个固定的写法。 1. 指定任务: `JobBuilder.newJob(任务.class) .withIdentity(任务名, 任务组).build();` 2. 指定cron表达式,创建Trigger: * `CronScheduleBuilder.cronSchedule(cron表达式);` * `TriggerBuilder.newTrigger().withIdentity(启动器的名字, 启动器的分组) .withSchedule(cron).build();` 3. 调用任务:`scheduler.scheduleJob(任务类型对象, 启动器对象)` /** * @ClassName * @Description * @Author:chengyunlai * @Date * @Version 1.0 **/ @RestController public class DynamicScheduleController { @Autowired private Scheduler scheduler; @GetMapping("/addSchedule") public String addSchedule() throws SchedulerException { int random = ThreadLocalRandom.current().nextInt(1000); // 1. 创建JobDetail,指定定时任务实现类的类型 JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class) .withIdentity("test-schedule" + random, "test-group").build(); // 2. 创建Trigger,并指定每3秒执行一次 CronScheduleBuilder cron = CronScheduleBuilder.cronSchedule("0/3 * * * * ?"); Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test-trigger" + random, "test-trigger-group") .withSchedule(cron).build(); // 3. 调度任务 scheduler.scheduleJob(jobDetail, trigger); return "success"; } 复制代码 通过浏览器输入项目的地址,一般默认是`localhost:8080/addSchedule`,输入后即可看到控制台输出了任务执行的输出内容。 ### 持久化 ### 如果工程重启了,上面的`SimpleJob`这个定时任务并不会重新启动。解决的办法就是将任务持久化,`Quartz`提供了解决方案,SpringBoot简化了这个操作。我们只需要配置好:数据库、数据源、操作数据库的JDBC即可。 依赖: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> 复制代码 1. 使用mysql数据库:导入它的驱动,mysql-connector-java。 2. 使用Druid作为我们的数据源:druid。 3. 使用spring-jdbc,帮助我们自动将任务信息存入到数据库中。 #### 配置 #### # 设置将定时任务的信息保存到数据库 spring.quartz.job-store-type=jdbc # 每次应用启动的时候都初始化数据库表结构 # 如果 spring.quartz.jdbc.initialize-schema 设置为 always 的话有个问题:每次重启应用的时候,跟 Quartz 相关的表会被删除重建! # 所以为了避免表被重复创建,我们可以提前创建表,然后将其指定为never spring.quartz.jdbc.initialize-schema=never # 数据库配置 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/scheduled?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root 复制代码 #### Quartz为我们准备了sql数据表 #### 官网:[Downloads (quartz-scheduler.org)][Downloads _quartz-scheduler.org] 以我:quartz-2.3.0-SNAPSHOT为例子: 下载源码后,找到`jdbcjobstore`这个目录: `quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore` 然后会有一系列的`sql`文件,找到和你数据库匹配的那个sql文件即可,我用的是mysql。 ![format_png][] 执行SQL文件建表,我的数据库名是:`scheduled`,各位从我的url中应该也能看出来。 建表完成后,所有配置工作结束了,启动程序,重新在浏览器中输入:`localhost:8080/addSchedule`,然后刷新一下数据库,就会发现任务被持久化了,此时重启工程后,该任务依旧会自动执行。 ### 暂停任务和删除任务 ### 我们在手动开启该任务的时候会指定: 1. 任务的名称和组 JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class) .withIdentity(任务名,任务组).build(); 复制代码 在暂停和恢复任务时,就需要用`JobKey.jobKey(任务名,任务组)`,得到一个`JobKey`,然后使用`scheduler.pauseJob(jobkey)`即可暂停任务;`scheduler.resumeJob(jobKey)`恢复任务。 1. 删除任务的时候需要将任务和Trigger都删除,而在上面我们可以拿到这个`jobkey`表示任务,我们也需要拿到trigger,同样的我们也定义过启动器的名字和分组。 `TriggerBuilder.newTrigger().withIdentity(启动器的名字, 启动器的分组) .withSchedule(cron).build();` 复制代码 `TriggerKey.triggerKey((启动器的名字, 启动器的分组);`也可以拿到`trigger`表示启动器。 * 通过以下顺序完整删除任务 * // 停止触发器 * scheduler.pauseTrigger(triggerKey); * // 移除触发器 * scheduler.unscheduleJob(triggerKey); * // 删除任务 * scheduler.deleteJob(jobKey); // 暂停 @GetMapping("/pauseSchedule") public String pauseSchedule(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); // 获取定时任务 JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null) { return "error"; } scheduler.pauseJob(jobKey); return "success"; } // 恢复 @GetMapping("/remuseSchedule") public String remuseSchedule(String jobName, String jobGroup) throws SchedulerException { JobKey jobKey = JobKey.jobKey(jobName, jobGroup); // 获取定时任务 JobDetail jobDetail = scheduler.getJobDetail(jobKey); if (jobDetail == null) { return "error"; } scheduler.resumeJob(jobKey); return "success"; } // 删除定时任务 @GetMapping("/removeSchedule") public String removeSchedule(String jobName, String jobGroup, String triggerName, String triggerGroup) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup); JobKey jobKey = JobKey.jobKey(jobName, jobGroup); Trigger trigger = scheduler.getTrigger(triggerKey); if (trigger == null) { return "error"; } // 停止触发器 scheduler.pauseTrigger(triggerKey); // 移除触发器 scheduler.unscheduleJob(triggerKey); // 删除任务 scheduler.deleteJob(jobKey); return "success"; } 复制代码 ### 未来 ### 后续,我准备结合前端,做一个页面的定时任务功能。 [Downloads _quartz-scheduler.org]: http://www.quartz-scheduler.org/downloads/ [format_png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/22/0f6c227118ee4a6bb68f49f49e23a9c7.png
还没有评论,来说两句吧...