描述
Springboot 整合Quartz, 实现简单定时任务。
Quartz的JobStore配置使用MySQL进行存储。
spring-boot-starter-quartz jar中没有java代码,主要就是maven依赖。
MySQL数据库准备
使用官方源码中提供的Quartz建表语句进行mysql表的初始化。
https://github.com/quartz-scheduler/quartz/tree/master/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore
这里提供了多种不同类型的数据库脚本。(这脚本藏的太深了,找了好久QAQ)
脚本初始化完成,会生成以下几张表:
qrtz_blob_triggers
qrtz_calendars
qrtz_cron_triggers
qrtz_fired_triggers
qrtz_job_details
qrtz_locks
qrtz_paused_trigger_grps
qrtz_scheduler_state
qrtz_simple_triggers
qrtz_simprop_triggers
qrtz_triggers
代码
maven配置:
<?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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo.quartz</groupId>
<artifactId>quartz-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quartz-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-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
<scope>runtime</scope>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties配置:
server.port=8081
spring.application.name=quarz-demo
## db
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/quartz?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=123456
spring.quartz.scheduler-name=scheduler111
spring.quartz.auto-startup=true
spring.quartz.job-store-type=jdbc
spring.quartz.overwrite-existing-jobs=true
spring.quartz.properties.org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix = qrtz_
spring.quartz.properties.org.quartz.jobStore.dataSource = myDS
编写HelloJob
package com.demo.quartz.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("HelloJob executor:" + new Date());
}
}
为了将HelloJob 数据初始化到数据库中,创建了SchedulerServer.
注意:initSampleJob函数第一次执行后,数据库已经存在了这个job的定义,第二次应用启动会提示job已经存在的错误,所以第二次启动需要把initSampleJob()这个方式注释掉
package com.demo.quartz.server;
import com.demo.quartz.job.HelloJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class SchedulerServer {
private static Logger logger = LoggerFactory.getLogger(SchedulerServer.class);
@Autowired
private Scheduler scheduler;
@PostConstruct
public void initSampleJob() throws SchedulerException {
logger.info("initSampleJob ...");
JobDetail job = JobBuilder.newJob(HelloJob.class)
.withIdentity("myJob", "group1")
.build();
// Trigger the job to run now, and then every 40 seconds
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5) //每5秒执行一次
.repeatForever())
.build();
// Tell quartz to schedule the job using our trigger
scheduler.scheduleJob(job, trigger);
}
}
执行结果输出
2020-03-25 22:51:33.976 INFO 3544 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2020-03-25 22:51:33.978 INFO 3544 --- [ main] com.demo.quartz.QuartzDemoApplication : Started QuartzDemoApplication in 2.138 seconds (JVM running for 2.858)
HelloJob executor:Wed Mar 25 22:51:37 CST 2020
HelloJob executor:Wed Mar 25 22:51:42 CST 2020
HelloJob executor:Wed Mar 25 22:51:47 CST 2020
HelloJob executor:Wed Mar 25 22:51:52 CST 2020
HelloJob executor:Wed Mar 25 22:51:57 CST 2020
HelloJob executor:Wed Mar 25 22:52:02 CST 2020
HelloJob executor:Wed Mar 25 22:52:07 CST 2020
思考:
- 实际业务中,如何动态添加Job?
- 如何让Job对象能够被容器管理?
- 业务逻辑代码需要访问其他数据库,需要在应用中配置多个数据源
网友评论