Quartz配置文件quartz.properties加载
前天,同事来问我,quatz任务调度的qurtaz.properties配置文件是如何加载的,项目是老大写的,我没看过代码,于是去翻了一遍源码,终于找到了配置的加载地方,让我们一起来看看吧。
首先从org.quartz.Scheduler实例化的地方开始入手,实例化的代码为:
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler sched = schedulerFactory.getScheduler();
SchedulerFactory是个接口,有两个实现类,在Eclipse下按下F4可以看到其继承图,如下图所示:
分别为:org.quartz.impl.DirectSchedulerFactory和org.quartz.impl.StdSchedulerFactory,我专门查看了一下源码,然后还找了一堆资料,查看这两个之间的区别。DirectSchedulerFactory的实例化比较复杂,需要用户提供一系列的参数来实例化,而StdSchedulerFactory则是利用quartz.properties配置文件参数来实例化对象。下面来看一下Scheduler实例化的配置。首先调用SchedulerFactory.getScheduler的时候,会先判断配置文件是否为空,如果第一次没有实例化,会先调用:initialize方法来读取properties配置文件,getScheduler方法源码如下图所示:
然后一起来看一下initialize方法源码吧
public void initialize() throws SchedulerException {
// short-circuit if already initialized
if (cfg != null) {
return;
}
if (initException != null) {
throw initException;
}
//PROPERTIES_FILE 的值为org.quartz.properties
String requestedFile = System.getProperty(PROPERTIES_FILE);
String propFileName = requestedFile != null ? requestedFile
: "quartz.properties";
File propFile = new File(propFileName);
Properties props = new Properties();
InputStream in = null;
try {
if (propFile.exists()) {
in = new BufferedInputStream(new FileInputStream(propFileName));
props.load(in);
} else if (requestedFile != null) {
in=
Thread.currentThread().getContextClassLoader().getResourceAsStream(requestedFile);
in = new BufferedInputStream(in);
try {
props.load(in);
} else {
propSrc = "default resource file in Quartz package: 'quartz.properties'";
ClassLoader cl = getClass().getClassLoader();
if(cl == null)
cl = findClassloader();
if(cl == null)
throw new SchedulerConfigException("Unable to find a class loader on the current thread or class.");
in = cl.getResourceAsStream(
"quartz.properties");
if (in == null) {
in = cl.getResourceAsStream(
"/quartz.properties");
}
if (in == null) {
in = cl.getResourceAsStream(
"org/quartz/quartz.properties");
}
if (in == null) {
initException = new SchedulerException(
"Default quartz.properties not found in class path");
throw initException;
}
try {
props.load(in);
} catch (IOException ioe) {
initException = new SchedulerException(
"Resource properties file: 'org/quartz/quartz.properties' "
+ "could not be read from the classpath.", ioe);
throw initException;
}
}
} finally {
if(in != null) {
try { in.close(); } catch(IOException ignore) { /* ignore */ }
}
}
initialize(overrideWithSysProps(props));
}
可以看到这个流程的配置文件查找实例化顺序为
1.先从环境变量org.quartz.properties查找,配置文件,如果不存在则利用默认配置文件,quartz.properties
2.然后从当前线程路径中读取org.quartz.properties环境变量文件,如果org.quartz.properties环境变量中的值不存在,则读取quartz.properties文件,如果两个都不存在,则执行第三步读取配置文件
3.分别读取从目录读取quartz.properties,/quartz.properties,org/quartz/quartz.properties,如果这3个目录下的quartz.properties配置文件不存在的,会抛出异常,实例化失败
最后添加配置文件的详细内容:
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore