applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd" default-lazy-init="false"> <context:annotation-config /> <context:component-scan base-package="com"></context:component-scan> <!--===================================================================== --> <!-- 配置外部变量文件 --> <!--===================================================================== --> <util:properties id="propertyConfigurer" location="classpath:springProject.properties"/> <context:property-placeholder properties-ref="propertyConfigurer" /> <import resource="applicationContext-<a style="BACKGROUND-IMAGE: none; POSITION: static; OUTLINE-STYLE: none; OUTLINE-COLOR: invert; OUTLINE-WIDTH: medium; DISPLAY: inline; COLOR: rgb(0,0,240); TEXT-DECORATION: none" href="http://www.so.com/s?q=quartz&ie=utf-8&src=se_lighten_f" target="_blank">quartz</a>.xml"/> <bean id="helloService" class="com.spring.test.HelloService"> <property name="name"> <value>${name}</value> </property> <property name="age"> <value>${age}</value> </property> </bean> </beans>
applicationContext-quartz.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <!-- 在<Beans>中设置default-autowire="byName"的属性,不能通过Bean名称自动注入,必须通过明确引用注入 --> <beans default-autowire="byName"> <!-- MyJob Configuration Start --> <bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="name" value="myJobDetail" /> <property name="group" value="springProject" /> <property name="volatility" value="false" /> <property name="durability" value="true" /> <property name="jobClass" value="com.spring.test.quartz.MyJob" /> <property name="jobDataAsMap"> <map> <entry key="count" value="0"></entry> </map> </property> </bean> <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="name" value="myJobTrigger" /> <property name="group" value="springProject" /> <property name="jobDetail" ref="myJobDetail" /> <!--<property name="startDelay" value="50000" /> --> <property name="misfireInstruction"> <value>#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_FIRE_ONCE_NOW}</value> </property> <property name="cronExpression"> <value>${quartz.myJob.cronExpression}</value> </property> </bean> <!-- MyJob Configuration End --> <!-- SimpleJob Configuration Start --> <bean name="simpleJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="name" value="simpleJobDetail" /> <property name="group" value="springProject" /> <property name="volatility" value="false" /> <property name="durability" value="true" /> <property name="jobClass" value="com.spring.test.quartz.SimpleJob" /> <property name="jobDataAsMap"> <map> <entry key="name" value="张三"></entry> <entry key="age" value="25"></entry> <entry key="count" value="0"></entry> </map> </property> <property name="applicationContextJobDataKey" value="applicationContext"/> </bean> <bean id="simpleJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="name" value="simpleJobTrigger" /> <property name="group" value="springProject" /> <property name="jobDetail" ref="simpleJobDetail" /> <!--<property name="startDelay" value="50000" /> --> <property name="misfireInstruction"> <value>#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_FIRE_ONCE_NOW}</value> </property> <property name="cronExpression"> <value>${quartz.simpleJob.cronExpression}</value> </property> </bean> <!-- SimpleJob Configuration End --> <!-- LogService Configuration Start --> <bean id="logServiceJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="logService" /> <property name="targetMethod" value="log" /> <property name="concurrent" value="false" /> </bean> <bean id="logServiceJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="name" value="logServiceJobTrigger" /> <property name="group" value="springProject" /> <property name="jobDetail" ref="logServiceJobDetail" /> <!--<property name="startDelay" value="50000" /> --> <property name="misfireInstruction"> <value>#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_FIRE_ONCE_NOW}</value> </property> <property name="cronExpression"> <value>${quartz.logServiceJob.cronExpression}</value> </property> </bean> <!-- LogService Configuration End --> <!-- scheduler --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="myJobTrigger" /> <ref bean="simpleJobTrigger" /> <ref bean="logServiceJobTrigger" /> </list> </property> <property name="overwriteExistingJobs" value="true" /> <property name="configLocation" value="classpath:quartz.properties"></property> </bean> </beans>
springProject.properties:
name=张三
age=20
american.name=American
chinese.name=Chinese
#Quartz Job cronExpression配置
quartz.myJob.cronExpression=0/15 * * * * ? *
quartz.simpleJob.cronExpression=0/10 * * * * ? *
quartz.logServiceJob.cronExpression=0/5 * * * * ? *
quartz.properties:
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
#org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass= org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate
org.quartz.jobStore.misfireThreshold = 60000
#org.quartz.jobStore.useProperties = true
#org.quartz.jobStore.tablePrefix = SPRING_PROJECT_QRTZ_
#org.quartz.jobStore.isClustered = true
#org.quartz.jobStore.clusterCheckinInterval = 15000
log4j.properties:
## LOGGERS ##
#define a logger
#log4j.rootLogger=DEBUG,console,file
log4j.rootLogger=INFO,console,file
## APPENDERS ##
# define an appender named console, which is set to be a ConsoleAppender
log4j.appender.console=org.apache.log4j.ConsoleAppender
# define an appender named file, which is set to be a RollingFileAppender
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=d:/demo_log.txt
#set the log's size
log4j.appender.file.MaxFileSize=1000KB
log4j.appender.file.MaxBackupIndex=20
## LAYOUTS ##
# assign a SimpleLayout to console appender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
# assign a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
# For debug
# log4j.appender.file.layout.ConversionPattern=[%-5p][%t][%C][%d{yyyy-MM-dd HH:mm:ss}] %m%n
# For deployment
log4j.appender.file.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}] %m%n
所需的JAR:
MyJob.java:
package com.spring.test.quartz;
import java.util.Date;
import java.util.Map;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MyJob extends QuartzJobBean implements StatefulJob{
@Override
protected void executeInternal(JobExecutionContext ctx)
throws JobExecutionException {
System.out.println("Now:" + new Date());
Map<String,Object> dataMap = ctx.getJobDetail().getJobDataMap();
Integer count = Integer.valueOf((String)dataMap.get("count"));
count += 1;
System.out.println("==============Count:" + count + "===============");
dataMap.put("count", String.valueOf(count));
}
}
SimpleJob.java:
package com.spring.test.quartz;
import java.util.Date;
import java.util.Map;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import com.spring.test.HelloService;
public class SimpleJob implements Job{
@Override
public void execute(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("Job [" + ctx.getTrigger().getName() + "] triggered.Time is :" + new Date());
// 配置jobDataAsMap,可以存储一些数据
Map<String, Object> dataMap = ctx.getJobDetail().getJobDataMap();
String username = (String) dataMap.get("name");
String age = (String) dataMap.get("age");
System.out.println("DataMap :name=" + username + ",age =" + age);
// 配置applicationContextSchedulerContextKey,可以获得applicationContext
ApplicationContext ac = (ApplicationContext) dataMap.get("applicationContext");
HelloService hs = ac.getBean(HelloService.class);
hs.test();
Integer count = Integer.valueOf((String)dataMap.get("count"));
System.out.println("--------count=" + count + "----------------");
dataMap.put("count", String.valueOf(count++));
}
}
LogService.java:
package com.spring.test.quartz;
import java.util.Date;
import org.springframework.stereotype.Service;
@Service("logService")
public class LogService {
public void log() {
System.out.println("[INFO] LogService:" + new Date());
}
}
只要Spring容器被加载,Jobs就会自动启动。
控制台部分内容:
ob [simpleJobTrigger] triggered.Time is :Tue Aug 12 11:23:40 CST 2014
DataMap :name=张三,age =25
==name=????,age=20
--------count=0----------------
[INFO] LogService:Tue Aug 12 11:23:40 CST 2014
[INFO] LogService:Tue Aug 12 11:23:45 CST 2014
Now:Tue Aug 12 11:23:45 CST 2014
==============Count:1===============
[INFO] LogService:Tue Aug 12 11:23:50 CST 2014
Job [simpleJobTrigger] triggered.Time is :Tue Aug 12 11:23:50 CST 2014
DataMap :name=张三,age =25
==name=????,age=20
--------count=0----------------
[INFO] LogService:Tue Aug 12 11:23:55 CST 2014
[INFO] LogService:Tue Aug 12 11:24:00 CST 2014
Now:Tue Aug 12 11:24:00 CST 2014
==============Count:2===============
Job [simpleJobTrigger] triggered.Time is :Tue Aug 12 11:24:00 CST 2014
DataMap :name=张三,age =25
==name=????,age=20
--------count=0----------------
[INFO] LogService:Tue Aug 12 11:24:05 CST 2014
[INFO] LogService:Tue Aug 12 11:24:10 CST 2014
Job [simpleJobTrigger] triggered.Time is :Tue Aug 12 11:24:10 CST 2014
DataMap :name=张三,age =25
==name=????,age=20
--------count=0----------------
[INFO] LogService:Tue Aug 12 11:24:15 CST 2014
Now:Tue Aug 12 11:24:15 CST 2014
==============Count:3===============
可以看出,StatefulJob可以保存Jobs运行的一些数据,而Job不可以。
可以通过org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean来将任意一个Bean作为一个Job。