非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教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- iPhone手机越狱-逆向砸壳-代码注入
- Flutter基础widgets教程-SizedBox篇
- 详解linux 看门狗驱动编写
- CentOS 6.5平台本地YUM配置的方法
- Linux环境(CentOS6.7 64位)下安装subversion1.9.5的方法
- CentOS 6.5平台实现快速部署FTP的方法
- Linux系统中sudo命令的十个技巧总结
- 详解linux电源管理驱动编写
- CentOS6.5系统简单安装与配置Nginx服务器的方法
- 详解linux 摄像头驱动编写
- Ubuntu16.04搭建NFS 文件共享服务器的方法
- 详解linux pwm驱动编写
- Ubuntu 16.04 LTS系统里中文txt文件打开的问题解决
- linux nand flash驱动编写
- 在Linux中使用Vundle管理Vim插件的方法