一、 新建quartz工程

新建java工程IsmpQuartz,在build path中加入用户库quartz15(我们使用quartz1.5版本),其中有commons-beanutils.jar、commons-collections-3.1.jar、commons-digester-1.7.jar、commons-logging.jar、quartz-1.5.0.jar、log4j-1.2.11.jar六个jar包。


二、 配置log4j

在src目录下新建log4j.properties,内容:

# Create stdout appender

log4j.rootLogger=error, stdout


# Configure the stdout appender to go to the Console

log4j.appender.stdout=org.apache.log4j.ConsoleAppender


# Configure stdout appender to use the PatternLayout

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout


# Pattern output the caller's filename and line #

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F/:%L) - %m%n


# Print messages of level INFO or above for examples

log4j.logger.ydtf.quartz=info,stdout


注意最后一句,我们定义一个名为ydtf.quartz的logger(日志器),其日志级别定为info(及以上),appender(输出方式)为stdout(即控制台),这样以ydtf.quartz包下的类名来获取logger(日志器)时,只有info以上级别(包括error)才可以使用log4j。

对于根日志器,我们过滤了error以下级别的输出,因为quartz自己输出的info级别和debug级别的信息实在太多,我们不得不过滤掉。

此外,需要注意对于 stdout这样的输出方式,我们专门为它设计了一个输出模板:

%5p 表示输出占5个字符的优先级,即error、info等字样

[%t] 表示输出线程名并用中括号括住,即[xxxx.class]等字样

(%F/:%L) 表示输出“类名:行号”信息,并用圆括号括住

%m%n 表示输出信息内容,最后以回车符结束


*注,如果log4j出现重复输出的情况,比如下面,每次消息都打印两次:

这并不是工作线程被同时执行了两次,而是log4j对一条信息进行了重复输出。请在log4j.properties的最后加上此句:

log4j.additivity.ydtf.quartz=false

即可消除重复输出问题。

三、 书写工作线程

新建类SyncServiceConsumeJob,实现Job接口:

package ydtf.quartz;

import java.util.Date;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.quartz.Job;

import org.quartz.JobDataMap;

import org.quartz.JobDetail;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class SyncServiceConsumeJob implements Job{

static Log logger = LogFactory.getLog(SyncServiceConsumeJob.class);


public void execute(JobExecutionContext context)

throws JobExecutionException {

JobDetail jobDetail = context.getJobDetail();


// The name is defined in the job definition

String jobName = jobDetail.getName();


// The directory to scan is stored in the job map

JobDataMap dataMap = jobDetail.getJobDataMap();

String doSth = dataMap.getString("DO_SOMETHING");


// Log the time the job started

logger.info(jobName + " "+doSth+" at " + new Date());

}

}

四、 书写调度器

调度器是一个主线程,由他来启动Scheduler实例(由quartz实现,它会启动指定的工作线程):

package ydtf.quartz;


import java.util.Date;


import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.quartz.Scheduler;

import org.quartz.SchedulerException;

import org.quartz.impl.StdSchedulerFactory;


public class SimpleScheduler {


static Log logger = LogFactory.getLog(SimpleScheduler.class);


public static void main(String[] args) {

SimpleScheduler simple = new SimpleScheduler();

simple.startScheduler();

}


public void startScheduler() {

Scheduler scheduler = null;


try {

// Get a Scheduler instance from the Factory

scheduler = StdSchedulerFactory.getDefaultScheduler();


// Start the scheduler

scheduler.start();

logger.info("Scheduler started at " + new Date());


} catch (SchedulerException ex) {

// deal with any exceptions

logger.error(ex);

}

}

}


五、 配置quartz的工作方式quartz.properties

在src目录下新建quartz.properties文件如下:

#===============================================================

#Configure Main Scheduler Properties

#===============================================================

org.quartz.scheduler.instanceName = QuartzScheduler #指定调度器实例名

org.quartz.scheduler.instanceId = AUTO #指定实例id自动分配


#===============================================================

#Configure ThreadPool

#===============================================================

org.quartz.threadPool.threadCount = 1 #线程的线程数1,即单线程

org.quartz.threadPool.threadPriority = 5 #线程优先级1-10之间

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool#线程池实现类


#===============================================================

#Configure JobStore

#===============================================================

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore#Job 存储在内存中


#===============================================================

#Configure Plugins

#===============================================================

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin#该插件使用quartz_jobs.xml

org.quartz.plugin.jobInitializer.overWriteExistingJobs = true

org.quartz.plugin.jobInitializer.failOnFileNotFound = true

org.quartz.plugin.jobInitializer.validating=false


六、 配置job,quartz_jobs.xml

<?xml version='1.0' encoding='gbk'?>


<quartz>


<job>

<job-detail>

<name>SyncServiceConsumeJob</name>

<group>DEFAULT</group>

<description>

同步业务执行消息

</description>

<job-class>

ydtf.quartz.SyncServiceConsumeJob

</job-class>

<volatility>false</volatility>

<durability>false</durability>

<recover>false</recover>

<job-data-map allows-transient-data="true">

<entry>

<key>DO_SOMETHING</key>

<value>同步业务执行消息</value>

</entry>

</job-data-map>

</job-detail>


<trigger>

<simple>

<name>Trigger1</name>

<group>DEFAULT</group>

<job-name>SyncServiceConsumeJob</job-name>

<job-group>DEFAULT</job-group>

<start-time>2009-08-27T1:00:00</start-time>

<!-- 每10秒无限循环 -->

<repeat-count>-1</repeat-count>

<repeat-interval>10000</repeat-interval>

</simple>

</trigger>


</job>

</quartz>


七、 以run as java application方式运行SimpleScheduler。


总结:

1、 导入quartz所需的包(6个)

2、 配置log4j.properties

3、 编写job类

4、 编写Scheduler类

5、 配置quartz.properties

6、 配置quartz_jobs.xml