当前位置: 首页 > news >正文

Quartz框架之Job和JobDetail(2)

1 无状态任务

由上章节可知,Job接口是具体的任务逻辑类必须要实现的接口

public class HelloJob  implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        StringJoiner joiner=new StringJoiner(" ")
                .add("hello")
                .add(DateUtil.getDateTime(new Date()))
                .add(Thread.currentThread().getName())
                .add(jobExecutionContext.getTrigger().getKey().getName());

        System.out.println(joiner.toString());
    }
}

在JobBuilder创建JobDetail实例时,我们通过传递任务类型的方式告知触发器将要触发的任务。

// newJob方法是JobBuilder类提供的静态方法
 JobDetail job = newJob(HelloJob.class)
                 .withIdentity("job1", "group1")
                 .build();

每次触发时,通过任务类型的无参数构造函数实例化HelloJob 对象,然后再执行实例对象中的execute方法。任务结束后,这个任务实例对象将被垃圾回收器回收。
为了演示每次触发时,quartz框架都会重新创建任务实例,HelloJob中增加无参数构造方法

 public HelloJob(){
        System.out.println("我被构造了"+this.hashCode());
    }

同样使用上篇文章中的代码样例 quartz(1),此时控制台输出

2022-09-26 19:36:24.546  INFO 2212 ---
我被构造了10703978
hello 2022-09-26 19:36:24
我被构造了10692626
hello 2022-09-26 19:36:27
我被构造了22832069
hello 2022-09-26 19:36:30
我被构造了9617674
hello 2022-09-26 19:36:33
我被构造了14815745
hello 2022-09-26 19:36:36
.......

通过输出可知每次调用execute前,均先实例化HelloJob对象【不是同一个对象,hashcode码不一样】。无参数构造方法意味着HelloJob任务的执行中不包含任务的信息,意味着这是一个无状态的任务

2 有状态任务

与任务的执行过程中,不包含任何外来的参数信息相反,有状态任务意味着任务的执行需要外部的条件,比如有一个高温预警任务,需要判定当前温度是否为高温(大于39摄氏度),并决定是否发送短信通知。这里就有一个参数决定任务的执行逻辑,当前温度。显然我们只能通过无参数构造的方法实例化任务逻辑对象,但是我们可以用JobDataMap存放Job执行的外部信息。

JobDataMap 可用于保存您希望在作业实例执行时可供其使用的任意数量的(可序列化)数据对象。JobDataMap 是 Java 映射接口的实现,并且增加了一些用于存储和检索基元类型数据的便捷方法。
JobDetail和Trigger中都可以包含自己的JobDataMap

实例代码如下


public class HelloDataJobimplements Job {
   @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        StringJoiner joiner=new StringJoiner(" ")
                .add("hello every one")
                .add("I am "+jobExecutionContext.getJobDetail().getJobDataMap().get("name"))
                .add("I am "+jobExecutionContext.getJobDetail().getJobDataMap().get("age"))
                .add(DateUtil.getDateTime(new Date()))
                .add("triggered by "+jobExecutionContext.getTrigger().getJobDataMap().get("trigger_name"));

        System.out.println(joiner.toString());
    }
}
    @Test
    void moreAboutJob(){
        try {
            // Grab the Scheduler instance from the Factory
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // and start it off
            scheduler.start();


            // define the job and tie it to our HelloJob class
            JobDetail job = newJob(HelloDataJob.class)
                    .withIdentity("job1", "group1")
                    .usingJobData("name","lyf")
                    .usingJobData("age",19)
                    .build();

            // Trigger the job to run now, and then repeat every 40 seconds
            Trigger trigger = newTrigger()
                    .withIdentity("trigger1", "group1")
                    .usingJobData("trigger_name","trigger1")
                    .startNow()
                    .withSchedule(simpleSchedule()
                            .withIntervalInSeconds(3)
                            .repeatForever())
                    .build();

            // Tell quartz to schedule the job using our trigger
            scheduler.scheduleJob(job, trigger);

            Thread.sleep(10000);
            scheduler.shutdown();

        } catch (SchedulerException | InterruptedException se) {
            se.printStackTrace();
        }
   }
hello every one I am lyf I am 19 2022-09-26 20:29:42 triggered by trigger1
hello every one I am lyf I am 19 2022-09-26 20:29:45 triggered by trigger1
hello every one I am lyf I am 19 2022-09-26 20:29:48 triggered by trigger1
hello every one I am lyf I am 19 2022-09-26 20:29:51 triggered by trigger1

3 Job和JobDetail的关系

首先得出结论,一个Job可被多个JobDetail同时引用,每个JobDetail中可存放具体实例定义的信息。这样设计的原因在于,每个任务逻辑执行的条件可能不同,那么就必须根据实际情形描述每个任务执行的其他信息。

比如,你可以创建一个类来实现名为“销售报告作业”的作业。可以对作业进行编码,以期望发送给它的参数(通过 JobDataMap)指定销售报表应基于的销售人员的姓名。然后,他们可以创建作业的多个定义(工作详细信息),例如“Joe”和“mike”

当触发器触发时,将加载它所关联的 JobDetail(实例定义),并通过计划程序上配置的 JobFactory 实例化它所引用的作业类。默认的作业工厂只是在作业类上调用 newInstance(),然后尝试调用与 JobDataMap 中的键名称匹配的类上的 setter 方法。也可能希望创建自己的 JobFactory 实现来完成一些事情,例如让应用程序的 IoC 或 DI 容器生成/初始化作业实例。

相关文章:

  • C语言刷题(二)
  • 【毕业设计】机器学习股票大数据量化分析与预测系统 - python 毕业设计
  • Ubuntu下安装opencv
  • 手把手带你刷好题(牛客刷题⑦)
  • Java保证线程安全的方式有哪些?
  • 《数据结构》队列及其经典面试题
  • 计算机图形学(十一):真实感图形(光照模型、材质模型)
  • 【云原生】Hadoop HA on k8s 环境部署
  • 四元数是什么
  • 大衣哥家里再添喜事,生产厂家免费送给他一辆新车
  • 爬取疫情数据并存到mysql数据库
  • 场景应用:网络的子网掩码为255.255.240.0,它能够处理的主机数是多少?
  • Qt5开发从入门到精通——第七篇六节( 图形视图—— 图元的旋转、缩放、切变、和位移)
  • 内网穿透工具natapp的注册、下载、安装与使用(详细教程)
  • CDH openssl 安装报错 TXT_DB error number 2
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • ECS应用管理最佳实践
  • ESLint简单操作
  • Hibernate最全面试题
  • JavaScript标准库系列——Math对象和Date对象(二)
  • java中的hashCode
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • React Native移动开发实战-3-实现页面间的数据传递
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Zepto.js源码学习之二
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 基于HAProxy的高性能缓存服务器nuster
  • 实习面试笔记
  • 使用parted解决大于2T的磁盘分区
  • 小程序button引导用户授权
  • 一道闭包题引发的思考
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • $.ajax()
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (Ruby)Ubuntu12.04安装Rails环境
  • (八)Flask之app.route装饰器函数的参数
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (黑马C++)L06 重载与继承
  • (三)uboot源码分析
  • (三分钟)速览传统边缘检测算子
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (一)kafka实战——kafka源码编译启动
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (已解决)什么是vue导航守卫
  • (转)EXC_BREAKPOINT僵尸错误
  • *上位机的定义
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET 反射 Reflect
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • [Android] 240204批量生成联系人,短信,通话记录的APK