首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >非Spring项目管理Quartz

非Spring项目管理Quartz

作者头像
每天学Java
发布2020-08-25 09:41:37
7180
发布2020-08-25 09:41:37
举报
文章被收录于专栏:每天学Java每天学Java

了解过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;
    }

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档