Quartz衍生出的三种任务类型,你用过几个?

简介: `Quartz`内部没有明确的任务类型的概念,在`ApiBoot`中对其进行封装后才确切的定义了这个概念,可以根据业务场景按需选择适合的任务类型来构建执行的任务。

前言

Quartz内部没有明确的任务类型的概念,在ApiBoot中对其进行封装后才确切的定义了这个概念,可以根据业务场景按需选择适合的任务类型来构建执行的任务。

衍生的任务类型

ApiBootQuartz集成封装后,提供了如下三种的任务类型:

  • OnceJob:一次性任务,仅执行一次
  • CronJob:使用Cron表达式定义任务周期
  • LoopJob:指定循环次数的任务
注意事项:任务类型是任务的执行方式类型,并不是创建任务的类型,创建任务都是通过继承 QuartzJobBean来完成,同一个任务可以使用不同的类型执行。

演示项目

我们使用Idea创建一个SpringBoot项目,用于我们本章的演示项目,创建项目后添加ApiBoot Quartz相关的依赖到pom.xml文件内,如下所示:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--ApiBoot Quartz-->
  <dependency>
    <groupId>org.minbox.framework</groupId>
    <artifactId>api-boot-starter-quartz</artifactId>
  </dependency>
</dependencies>
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.minbox.framework</groupId>
      <artifactId>api-boot-dependencies</artifactId>
      <version>2.2.1.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

示例任务

我们来创建一个本章演示所需要的任务类,如下所示:

/**
 * 示例任务
 *
 * @author 恒宇少年
 */
public class DemoJob extends QuartzJobBean {
    /**
     * logger instance
     */
    static Logger logger = LoggerFactory.getLogger(DemoJob.class);

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        logger.info("这是一个示例任务,执行时间:{}", System.currentTimeMillis());
    }
}

当任务执行时就会在控制台输出任务执行的时间,继承自Spring提供的封装任务类QuartzJobBean,会自动扫描到DemoJob并通过反射创建实例后放入Ioc容器,具体的流程可以访问 这种方式整合Quartz你见过吗? 了解详情。

一次性任务

我们使用Once任务类型来执行上面创建的DemoJob示例任务,先上代码,如下所示:

/**
  * ApiBoot Quartz内置接口
  *
  * @see org.minbox.framework.api.boot.plugin.quartz.support.ApiBootQuartzServiceDefaultSupport
  */
@Autowired
private ApiBootQuartzService quartzService;

// 创建Once任务
quartzService.newJob(ApiBootOnceJobWrapper.Context().jobClass(DemoJob.class).wrapper());

我们只需要一行代码就可以来定义一个新的任务,在代码中出现了一个新面孔 ApiBootOnceJobWrapper

ApiBootOnceJobWrapper主要工作是来封装Once类型任务所需要的配置字段,内部通过Lombok提供的@Builder注解来实现,Once任务可配置的内容如下所示:

方法 默认值 描述
.jobClass(Class<? extends QuartzJobBean> jobClass) - 配置所执行的QuartzJobBean实现类类型
.jobKey(String jobKey) 随机UUID字符串 任务唯一key
.startAtTime(Date startAtTime) 当前时间 任务开始执行时间
.param(ApiBootJobParamWrapper param) - 任务执行时的参数列表封装对象

Cron表达式任务

Cron表达式来创建任务是比较灵活的,也是比较常用的方式,使用ApiBoot Quartz同样仅仅需要一行代码就可以实现,下面我们来定义每间隔一秒执行一次DemoJob内的任务逻辑,如下所示:

/**
  * ApiBoot Quartz内置接口
  *
  * @see org.minbox.framework.api.boot.plugin.quartz.support.ApiBootQuartzServiceDefaultSupport
  */
@Autowired
private ApiBootQuartzService quartzService;
// 创建Cron任务
quartzService.newJob(ApiBootCronJobWrapper.Context().jobClass(DemoJob.class).cron("0/1 * * * * ?").wrapper());

ApiBootCronJobWrapper 所做的工作与ApiBootOnceJobWrapper其实是一样的,都是用来采集Cron类型的任务所需要的配置字段,内部同样是通过Lombok提供的@Builder注解实现,Cron类型任务可配置的内容如下所示:

方法 默认值 描述
.jobClass(Class<? extends QuartzJobBean> jobClass) - 配置所执行的QuartzJobBean实现类类型
.jobKey(String jobKey) 随机UUID字符串 任务唯一key
.cron(String cron) - 任务执行时间的Cron表达式
.param(ApiBootJobParamWrapper param) - 任务执行时的参数列表封装对象

Loop循环任务

Loop类型的任务在开发中也是比较常用的,根据指定的循环次数以及每一次执行的间隔时间运行定时任务逻辑,当获取到期望的结果后还可以将任务自身进行删除,先来看看一个简单例子:

/**
  * ApiBoot Quartz内置接口
  *
  * @see org.minbox.framework.api.boot.plugin.quartz.support.ApiBootQuartzServiceDefaultSupport
  */
@Autowired
private ApiBootQuartzService quartzService;
// 创建Loop任务
quartzService.newJob(ApiBootLoopJobWrapper.Context().jobClass(DemoJob.class).loopIntervalTime(2000).repeatTimes(5).wrapper());
上面的定时任务会先执行1次后每 间隔2000毫秒再执行 5次,一共是执行 6次,大家注意配置。

可以看到Loop类型的任务也提供了一个 ApiBootLoopJobWrapper 来封装任务执行所需要的配置字段,可配置的字段方法如下所示:

方法 默认值 描述
.jobClass(Class<? extends QuartzJobBean> jobClass) - 配置所执行的QuartzJobBean实现类类型
.jobKey(String jobKey) 随机UUID字符串 任务唯一key
.loopIntervalTime(int intervalTime) 1000 循环执行的间隔时间,单位:毫秒
.repeatTimes(int times) 0 循环执行次数
.startAtTime(Date startAtTime) 当前时间 任务开始执行时间
.param(ApiBootJobParamWrapper param) - 任务执行时的参数列表封装对象
如果不设置 repeatTimes仅执行一次,效果与 Once一样。

运行测试

在运行项目之前先来修改项目的XxxApplication入口类,我们期望在项目启动完成后就执行任务,那么我们直接实现CommandLineRunner接口来完成这一需求,如下所示:

/**
 * ApiBoot Quartz 三种任务类型示例
 */
@SpringBootApplication
public class ApibootQuartzJobTypesApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(ApibootQuartzJobTypesApplication.class, args);
    }

    /**
     * ApiBoot Quartz内置接口
     *
     * @see org.minbox.framework.api.boot.plugin.quartz.support.ApiBootQuartzServiceDefaultSupport
     */
    @Autowired
    private ApiBootQuartzService quartzService;

    @Override
    public void run(String... args) throws Exception {
        // 一次性任务
        quartzService.newJob(ApiBootOnceJobWrapper.Context().jobClass(DemoJob.class).wrapper());

        // 循环执行任务,每隔2000毫秒执行一次,循环5次,一共执行6次
        quartzService.newJob(ApiBootLoopJobWrapper.Context().jobClass(DemoJob.class).loopIntervalTime(2000).repeatTimes(5).wrapper());

        // Cron表达式任务,间隔1秒执行一次
        quartzService.newJob(ApiBootCronJobWrapper.Context().jobClass(DemoJob.class).cron("0/1 * * * * ?").wrapper());
    }
}

启动项目后我们可以在控制台看到有任务执行时间输出,如下所示:

2019-12-24 14:56:05.046  INFO 3113 --- [eduler_Worker-1] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170565046
2019-12-24 14:56:05.046  INFO 3113 --- [eduler_Worker-2] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170565046
2019-12-24 14:56:05.047  INFO 3113 --- [eduler_Worker-3] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170565047
2019-12-24 14:56:06.005  INFO 3113 --- [eduler_Worker-4] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170566005
2019-12-24 14:56:07.002  INFO 3113 --- [eduler_Worker-5] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170567002
2019-12-24 14:56:07.042  INFO 3113 --- [eduler_Worker-6] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170567042
2019-12-24 14:56:08.003  INFO 3113 --- [eduler_Worker-7] o.minbox.chapter.apiboot.quartz.DemoJob  : 这是一个示例任务,执行时间:1577170568003
...
虽然任务已经执行了,但是由于是多种执行方式同时执行同一个任务,我们不好做出区分,针对这个问题可以使用 ApiBoot Quartz提供的参数来解决。

敲黑板,划重点

ApiBoot Quartz所提供的功能已经可以满足日常开发所需要,而且比较灵活,可以通过ApiBoot Quartz提供的Wrapper封装类的方法进行自定义配置,任务的执行是子线程异步操作,不需要考虑会影响访问响应的效率问题

代码示例

如果您喜欢本篇文章请为源码仓库点个Star,谢谢!!!
本篇文章示例源码可以通过以下途径获取,目录为apiboot-quartz-job-types

相关文章
|
2天前
|
JavaScript 前端开发 程序员
TypeScript【枚举、联合类型函数_基础、函数_参数说明 、类的概念、类的创建】(二)-全面详解(学习总结---从入门到深化)
TypeScript【枚举、联合类型函数_基础、函数_参数说明 、类的概念、类的创建】(二)-全面详解(学习总结---从入门到深化)
20 0
|
7月前
28activiti - 流程变量(支持的类型)
28activiti - 流程变量(支持的类型)
17 0
|
9月前
|
Java 调度
quartz(一)基础篇
quartz(一)基础篇
44 0
|
10月前
|
Java
SpringBoot枚举转化代码项统一解决方案
SpringBoot枚举转化代码项统一解决方案
72 0
|
JSON 前端开发 数据格式
Jackson动态扩展自定义字段
在日常开发中,会有些字段经常发生变化的类,但是每次都要修改数据传输类,例如前端需要额外新增一个 参数响应,或者业务上需要调整某些动态的字段等等,那如何解决此类问题呢。
371 0
Jackson动态扩展自定义字段
|
XML 存储 Java
Spring 核心特性之类型转换(PropertyEditor、ConversionService)
前言 与数据绑定一样,类型转换同样是 Spring 的核心特性之一,Spring 最初的配置信息主要以 XML 的形式存在,这就要求 Spring 将字符串形式的配置转换为具体的 Java 类型,经过多个版本的演进,Spring 中的类型转换功能愈发成熟。
242 0
Spring 核心特性之类型转换(PropertyEditor、ConversionService)
|
存储 Java 数据库连接
这种方式整合Quartz你见过吗?
`Quartz`是一款优秀的任务调度框架,支持内存、JDBC的形式来存储未执行的任务列表,支持多个任务节点同时执行任务,支持任务漂移到不同的节点执行。
|
开发框架 安全 搜索推荐
使用MapStruct自动化转换实体
``MapStruct``是一种类型安全的``bean映射``类生成java注释处理器。 我们要做的就是定义一个映射器接口,声明任何必需的映射方法。在编译的过程中,``MapStruct``会生成此接口的实现。该实现使用纯java方法调用的源和目标对象之间的映射,``MapStruct``节省了时间,通过生成代码完成繁琐和容易出错的代码逻辑。下面我们来揭开它的神秘面纱
|
XML Java 程序员
【如何让代码变“高级”(一)】-Spring组合注解提升代码维度(这么有趣)
在定义某个类或接口时,使用了Spring自带的注解(@Controller、@Service,@Conditional),同时又要使用公司特定的注解标注公司的业务,接着就出现了以下处理方式的那一幕。
197 0
|
Java 应用服务中间件
Quartz - 基础篇(下)
Quartz - 基础篇(下)
139 0
Quartz - 基础篇(下)