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/>
</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>
<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>
<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>
<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
jdbc:
initialize-schema: always
properties:
org:
quartz:
scheduler:
instanceName: AiCloudwalkSmpcGneteScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
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
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
messages:
basename: messages_zh
crons:
quartzJobFirst: 0/5 * * * *
?
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()
.build();
}
protected Trigger
triggerJob(String cros
, JobDetail jobDetail
){
return TriggerBuilder
.newTrigger()
.forJob(jobDetail
)
.withIdentity("triggerFor".concat(this.name
))
.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、运行结果
定时相关的表: