一, 关于 Quartz
Quartz 是 OpenSymphony 开源组织在 Job scheduling 领域又一个开源项目, 它可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用. 在 java 企业级应用中, Quartz 是使用最广泛的定时调度框架.
在 Quartz 中的主要概念:
Scheduler: 调度任务的主要 API
ScheduleBuilder: 用于构建 Scheduler, 例如其简单实现类 SimpleScheduleBuilder
Job: 调度任务执行的接口, 也即定时任务执行的方法
JobDetail: 定时任务作业的实例
JobBuilder: 关联具体的 Job, 用于构建 JobDetail
Trigger: 定义调度执行计划的组件, 即定时执行
TriggerBuilder: 构建 Trigger
一, Quartz 演示示例
在 SpringBoot 中, 我们需要引入 quartz 的依赖.
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!--quartz 定时调度依赖 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-quartz</artifactId>
- </dependency>
首先定义定时具体执行逻辑 Job, 创建类 QuartzJob1, 这里集继承 QuartzJobBean 实现 executeInternal 即可, 该方法即定时执行任务逻辑, 这里简单打印了下当前时间.
- public class QuartzJob1 extends QuartzJobBean {
- @Override
- protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- System.out.println("QuartzJob1----" + sdf.format(new Date()));
- }
- }
然后创建 QuartzConfig, 接着定义 JobDetail,JobDetail 由 JobBuilder 构建, 同时关联了任务 QuartzJob1.
- @Configuration
- public class QuartzConfig {
- @Bean
- public JobDetail jobDetail1(){
- return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
- }
- }
最后我们需要定义定时调度 Trigger, 简单实现类 SimpleScheduleBuilder 用于构建 Scheduler,TriggerBuilder 则用于构建 Trigger,
- @Configuration
- public class QuartzConfig {
- @Bean
- public JobDetail jobDetail1(){
- return JobBuilder.newJob(QuartzJob1.class).storeDurably().build();
- }
- @Bean
- public Trigger trigger1(){
- SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
- .withIntervalInSeconds(1) // 每一秒执行一次
- .repeatForever(); // 永久重复, 一直执行下去
- return TriggerBuilder.newTrigger()
- .forJob(jobDetail1())
- .withSchedule(scheduleBuilder)
- .build();
- }
- }
这样一个 Quartz 定时任务就配置完成了.
其实 Job 的定义也可以使用内部类, 这样可以省去 Job 类的创建, 例如下面定时任务 2 jobDetail2 和 trigger2.
- @Bean
- public JobDetail jobDetail2(){
- QuartzJobBean quartzJob2 = new QuartzJobBean() {
- @Override
- protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- System.out.println("内部类 quartzJob2----" + sdf.format(new Date()));
- }
- };
- return JobBuilder.newJob(quartzJob2.getClass()).storeDurably().build();
- }
- @Bean
- public Trigger trigger2(){
- //JobDetail 的 bean 注入不能省略
- //JobDetail jobDetail3 = JobBuilder.newJob(QuartzJob2.class).storeDurably().build();
- SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
- .withIntervalInSeconds(2) // 每 2 秒执行一次
- .repeatForever(); // 永久重复, 一直执行下去
- return TriggerBuilder.newTrigger()
- .forJob(jobDetail2())
- .withSchedule(scheduleBuilder).build();
- }
启动程序, 我们就可以看到控制台的时间输出了.
同时 Quartz 是支持数据持久化的, 可以将定时调度信息持久化到数据库.
选择持久化到数据库, 我们需要创建对应的表, 建表语句可以在 Quartz 官网 http://www.quartz-scheduler.org/downloads/ 进行下载, 解压后在 docs\dbTables 目录下寻找对应数据库的 SQL 脚本.
为了方便, 我也将该文件放在了项目源码 resources 里.
操作数据库, 我们引入相关的依赖. 若有 ORM 框架, 例如 mybatis,hibernate 或者 jpa, 则无需再引入 jdbc 依赖.
- <!--mysql 连接 -->
- <dependency>
- <groupId>MySQL</groupId>
- <artifactId>MySQL-connector-java</artifactId>
- <scope>runtime</scope>
- </dependency>
- <!--druid 连接池 -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.1.10</version>
- </dependency>
- <!--jdbc 依赖 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- </dependency>
在 application.YAML 配置文件中, 我们对 quartz 持久化方式进行声明.
- server:
- port: 10900
- spring:
- profiles:
- active: dev
- quartz:
- job-store-type: jdbc #持久化到数据库
- properties:
- org:
- quartz:
- datasource:
- # 新版驱动从 com.MySQL.jdbc.Driver 变更为 com.MySQL.cj.jdbc.Driver
- driver-class-name: com.MySQL.cj.jdbc.Driver
- # 数据源需要添加时间标准和指定编码格式解决乱码 You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
- url: jdbc:MySQL://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
- username: root
- password: 1234
- scheduler:
- instancName: clusteredScheduler
- instanceId: AUTO
- jobStore:
- class: org.quartz.impl.jdbcjobstore.JobStoreTX
- driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate 说明支持集群
- tablePrefix: QRTZ_
- isClustered: true
- clusterCheckinInterval: 1000
- useProperties: false
- threadPool:
- class: org.quartz.simpl.SimpleThreadPool
- threadCount: 20
- threadPriority: 5
这里主要就是 job-store-type: jdbc, 表示持久化到数据库, 然后就是数据源, 由于该演示项目没有其他 ORM 的数据源, 所以这里将数据源信息定义在了 quartz 节点下的 datasource 节点, 如果已经存在, 可使用同一个属性配置, 当然最关键的是 QuartzDataSource 声明.
这里关键的是 @QuartzDataSource, 这个要和项目中已经存在的数据源区分开.
- //Error:EmbeddedDatabaseType class not found,Druid 数据源初始化需要引入 spring-jdbc 依赖, JPA 或 mybatis 依赖已经包含该依赖
- @Bean
- @QuartzDataSource
- @ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
- DataSource quartzDataSource(){
- return DruidDataSourceBuilder.create().build();
- }
这样持久化就已经配置好了, 我们执行 sql, 再启动项目, 启动完成后, 我们可以看到数据库中已经有我们的定时调度数据了.
源码地址:
posted on 2019-11-09 23:02 杨小格子 阅读 (...) 评论 (...) 编辑 收藏
来源: https://www.cnblogs.com/imyanger/p/11828301.html