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 initializedif (cfg != null) {return;}if (initException != null) {throw initException;}//PROPERTIES_FILE 的值为org.quartz.propertiesString 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: falseorg.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: trueorg.quartz.jobStore.misfireThreshold: 60000org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore