SpringBoot-(10)quartz定时任务的配置和使用

it2025-03-04  23

quartz定时任务的配置与使用

有存在一类需求,是需要去定时执行的,此时就需要使用到定时任务。例如说,每分钟扫描超时支付的订单,每小时清理一次日志文件,每天统计前一天的数据并生成报表,每个月月初的工资单的推送,每年一次的生日提醒等等。

Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。

它有很多特征,如:数据库支持,集群,插件,EJB 作业预构建,JavaMail 及其它,支持 cron-like 表达式等等。

在 Quartz 体系结构中,有三个组件非常重要:

Scheduler :调度器Trigger :触发器Job :任务

1、导入依赖

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- 实现对 Quartz 的自动化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.48</version> </dependency> <!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>2.7.9</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> </project>

2、application.yml配置

logging: file: name: slf4j-test path: ./logs max-size: 10MB level: root: info config: classpath:logback-gnete.xml spring: datasource: driver-class-name: com.mysql.jdbc.Driver name: mybatis password: 123456 url: jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false username: root type: com.zaxxer.hikari.HikariDataSource hikari: minimum-idle: 100 maximum-pool-size: 500 auto-commit: true idle-timeout: 30000 pool-name: DatebookHikariCP max-lifetime: 1800000 connection-timeout: 30000 validation-timeout: 3000 quartz: job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。 jdbc: initialize-schema: always properties: org: quartz: scheduler: instanceName: AiCloudwalkSmpcGneteScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX # JobStore 实现类 driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix: QRTZ_ # Quartz 表前缀 isClustered: true # 是集群模式 clusterCheckinInterval: 10000 useProperties: false dataSource: quartzDataSource # 使用的数据源 dataSource: quartzDataSource: driver: com.mysql.jdbc.Driver URL: jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true user: root password: 123456 provider: hikaricp threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 # 线程池大小,默认为10 threadPriority: 5 # 线程优先级 threadsInheritContextClassLoaderOfInitializingThread: true messages: basename: messages_zh crons: quartzJobFirst: 0/5 * * * * ? #mybatis mybatis: mapper-locations: classpath*:mybatis/mysql/*.xml type-aliases-package: com.example.demo.entity

crons表达式的在线生成网站:http://www.bejson.com/othertools/cron/。

更多Quartz Scheduler 附加属性,可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html

3、自定义AbstractQuartzConfig类

package com.example.demo.configs; import org.quartz.*; public abstract class AbstractQuartzConfig { private String name = null; protected JobDetail job(Class <? extends Job> clazz){ this.name = clazz.getSimpleName(); return JobBuilder.newJob() .ofType(clazz) .withIdentity(name) .storeDurably() // 没有 Trigger 关联的时候任务是否被保留。因为创建 JobDetail 时,还没 Trigger 指向它,所以需要设置为 true ,表示保留。 .build(); } protected Trigger triggerJob(String cros, JobDetail jobDetail){ return TriggerBuilder.newTrigger() .forJob(jobDetail) // 对应 Job 为 jobDetail .withIdentity("triggerFor".concat(this.name)) // 名字为 triggerFor* .startNow() //立即启动 .withSchedule(CronScheduleBuilder.cronSchedule(cros).withMisfireHandlingInstructionDoNothing()) .build(); } }

4、自定义的QuartzConfig类

package com.example.demo.configs; import com.example.demo.job.QuartzJobFirst; import org.quartz.JobDetail; import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class QuartzConfig extends AbstractQuartzConfig{ @Value("${crons.quartzJobFirst}") private String cros; @Bean public JobDetail jobTest(){ return super.job(QuartzJobFirst.class); } @Bean public Trigger triggerJobTest(){ return super.triggerJob(cros,this.jobTest()); } }

传入yml文件中定义的crons。

使用@Bean自动设置。也可以手动设置。

5、创建QuartzJobFirst定时任务

package com.example.demo.job; import lombok.extern.slf4j.Slf4j; import org.quartz.DisallowConcurrentExecution; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; @Slf4j @DisallowConcurrentExecution public class QuartzJobFirst extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("————————————定时任务正在运行————————————"); } }

通过在 Job 实现类上添加 @DisallowConcurrentExecution 注解,实现在相同 Quartz Scheduler 集群中,相同 JobKey 的 JobDetail ,保证在多个 JVM 进程中,有且仅有一个节点在执行。

6、Application类

package com.example.demo; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @Slf4j @MapperScan({"com.example.demo.**.mapper"}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

7、项目结构

如图:

8、运行结果

定时相关的表:

最新回复(0)