专栏首页每天学Java非Spring项目管理Quartz

非Spring项目管理Quartz

了解过Quartz的同学可能会知道,在Quartz的默认配置中,执行的Job只是简单的调用job类的newInstance()方法来创建Job实例,这种方式执行的Job有时候并不能满足我们的需求,比如无法注入容器产生的实例。

在Spring项目中我们可能并不会过于关注Quartz,因为一些常见的问题(包含上面提到的注入)Spring已经帮我们处理好,如果你在非Spring项目中,集成Quartz后需要注入容器实例,那么这篇文章应该会对你有所帮助(文章不做Quartz的入门介绍)。

在Quartz的文档中,有这么一段描述:

JobFactory

当trigger触发时,通过Scheduler上配置的JobFactory实例化与之关联的jobs。
默认的JobFactory只是在jobs类上调用newInstance()。

您可能需要创建自己的JobFactory实现,
以完成诸如让应用程序的IoC或DI容器生成/初始化jobs实例之类的操作。

请参阅org.quartz.spi.JobFactory接口以及
相关的Scheduler.setJobFactory(fact) 方法。

这段话告诉我们默认的JobFactory(参考SimpleJobFactory类)只是在job类上调用newInstance()方法,我们如果想自定义类实例,可以自己去实现JobFactory,但并不是我们对JobFactory接口进行实现,实现类就会负责初始化Job实例的工作

这里先这里给出解决方案:

  • 实现JobFactory接口
  • 编写配置文件(quartz.properties)去指定JobFactory对应的实现类
  • 初始化,使配置文件的配置生效

上面的步骤中,相对于JobFactory接口的实现,更重要的一步是如何使JobFactory生效,下面具体分析如何实现。

在org.quartz.Scheduler接口中,有setJobFactory方法

void setJobFactory(JobFactory var1) throws SchedulerException;

由此可见,要想完成这一功能就需要在setJobFactory这里出发,在StdSchedulerFactory创建Scheduler的工厂类中,创建 JobFactory最核心的一步就是获取jobFactoryClass,

this.cfg.getStringProperty("org.quartz.scheduler.jobFactory.class",

cfg实际上配置文件的数据,读取后放到PropertiesParser对象中,在StdSchedulerFactory工厂类创建Scheduler的时候,会读取配置key为 org.quartz.scheduler.jobFactory.class的数据,如果读取不到那么默认为null,此时就会使用默认的JobFactory,所以我们要做的工作就是让其读取到,不走默认的JobFactory。

这里说的配置文件在Quartz源码中也默认有一份,但是该配置文件并未并未设置org.quartz.scheduler.jobFactory.class,所以我们需要自己去写一个配置文件(也可以不使用配置文件,因为初始化配置的方式有三种,这里我选用的是配置文件)

配置文件:

org.quartz.scheduler.jobFactory.class:quartz.JobFactoryAdapt

配置好之后,就需要让工厂类读取这个配置了,在StdSchedulerFactory工厂类中,提供了三个不同参数的initialize方法来设置配置文件(配置文件路径,文件流,直接构造Properties对象),下面代码红色字体即初始化配置过程。

StdSchedulerFactory stdSchedulerFactory =

到这里配置就会生效,Quartz生成需要执行Job的就会走我们自定义的JobFactory。在Quartz中JobFactory的设计,为我们实现自定义功能留了扩展的可能。

最后工厂类的实现就相对简单了,在返回实例前,通过上下文对需要注入的字段进行注入。

项目地址:https://github.com/xynuSuMu/jerry.git

public class JobFactoryAdapt implements JobFactory {

    //
    private JerryContext jerryContext = JerryContext.getInstance();

    @Override
    public Job newJob(TriggerFiredBundle triggerFiredBundle, Scheduler scheduler) throws SchedulerException {
        return newJob(triggerFiredBundle);
    }

    public Job newJob(TriggerFiredBundle bundle) throws SchedulerException {
        try {
            Object jobObject = createJobInstance(bundle);
            return adaptJob(jobObject);
        } catch (Exception ex) {
            throw new SchedulerException("Job instantiation failed", ex);
        }
    }

    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Method getJobDetail = bundle.getClass().getMethod("getJobDetail");
        Object jobDetail = getJobDetail.invoke(bundle);
        Method getJobClass = jobDetail.getClass().getMethod("getJobClass");
        Class jobClass = (Class) getJobClass.invoke(jobDetail);
        //为字段赋值
        Object o = jobClass.newInstance();
        Field[] fields = jobClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.get(o) == null) {
                Object proxy = jerryContext.getBean(field.getType().getName());
                if (proxy != null)
                    field.set(o, proxy);
            }
        }
        return o;
    }

    protected Job adaptJob(Object jobObject) throws Exception {
        return (Job) jobObject;
    }

}

本文分享自微信公众号 - 每天学Java(gh_fddfb9d03324),作者:每天学Java

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java底层-揭开JVM的面纱

    在计算机世界里,程序执行的实质是通过高低电位来触发电子元件的(数字电路的知识), 而高低电位可以认为是我们所说的二进制编码,所以最开始的编程其实就是写0、1组合...

    每天学Java
  • JDK常用命令行工具

    “ 给一个系统定位问题的时候,知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里的数据包括:运行日志、异常堆栈、GC日志、线程快照(threa...

    每天学Java
  • Java底层-HotSpot

    在前面几节我们聊到,Javac编译器将java文件编译为class文件后,由JVM将字节码转为与机器适配的机器码进行执行, 这里我们说的JVM实际上是JVM实例...

    每天学Java
  • Xenomai 概述

    • Provide environment for co-kernel real-time drivers

    ZC_Robot机器人技术
  • dubbox 增加google-gprc/protobuf支持

    好久没写东西了,今年实在太忙,基本都在搞业务开发,晚上来补一篇,作为今年的收官博客。google-rpc 正式发布以来,受到了不少人的关注,这么知名的rpc框架...

    菩提树下的杨过
  • 【Spring Boot 实战】数据库千万级分库分表和读写分离实战

    因为使用我们使用Sharding-JDBC Spring Boot Starter,所以还是只需要在properties配置文件配置主从库的数据源即可

    小东啊
  • 数据库千万级分库分表和读写分离之「SpringBoot实战」

    因为使用我们使用Sharding-JDBC Spring Boot Starter,所以还是只需要在properties配置文件配置主从库的数据源即可

    IT技术小咖
  • 06 Spring框架 依赖注入(三)多配置文件

    在Spring前几节的学习中我们都使用了一个配置文件,就像struts2中可以包含其他的配置文件,我们能不能使用多个配置文件呢(在工程比庞大,配置比较多的时候)...

    MindMrWang
  • kickstart模式实现批量安装centos7.x系统

    1.1 安装系统的方法   l  光盘(ISO文件,光盘的镜像文件)===>>每一台物理机都得给一个光驱,如果用外置光驱的话,是不是每台机器都需要插一下   l...

    惨绿少年
  • 用FBI通缉犯照片集,考验亚马逊人脸识别,意外发现了隐情

    自从亚马逊的人脸识别系统Rekognition,把28位美国议员认成了罪犯,他们就决定亲自实验一下。

    量子位

扫码关注云+社区

领取腾讯云代金券