<!--StartFragment-->
一、 新建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出现重复输出的情况,比如下面,每次消息都打印两次:
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:585pt; height:50pt'> <v:imagedata src="file://localhost/Users/kmyhy/Library/Caches/TemporaryItems/msoclip/0/clip_image001.png" mce_src="file://localhost/Users/kmyhy/Library/Caches/TemporaryItems/msoclip/0/clip_image001.png" o:title="" /> </v:shape><![endif]-->
这并不是工作线程被同时执行了两次,而是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
<!--EndFragment-->