Spring+Quartz整合
2015-06-11 10:00
423 查看
Quartz是一个非常优秀的任务调度引擎,详情请见官网:http://www.quartz-scheduler.org/
而Spring很好地集成了Quartz,为企业级的任务调度提供了方便。
下面先看一个实现了Job接口的任务HelloWorldJob:
Java代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
package com.springQuartz.example;
import java.util.Map;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloWorldJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Map properties = context.getMergedJobDataMap();
System.out.println("Hello World!");
System.out.println("Previous Fire Time: "+context.getPreviousFireTime());//上次触发任务的时间
System.out.println("Current Fire Time: "+context.getFireTime());//当然触发时间
System.out.println("Next Fire Time: "+context.getNextFireTime());//下次触发时间
System.out.println(properties.get("message"));
System.out.println();
}
}
这个Job输出"HelloWorld",同时输出上次、本次及下次触发的时间。
我们看一下在applicationContext.xml中的配置:
Xml代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
<bean id="job" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.springQuartz.example.HelloWorldJob"/>
<property name="jobDataAsMap">
<map>
<entry key="triggerMessage" value="Job Message In JobDetail"/> <!--设置JobDetail中的值-->
</map>
</property>
</bean>
<bean id="trigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="job"/> <!--触发的job引用-->
<property name="startDelay" value="1000"/> <!--设置延迟1秒后运行-->
<property name="repeatInterval" value="10000"/> <!--设置每10秒触发一次-->
<property name="jobDataAsMap">
<map>
<entry key="triggerMessage" value="Job Message From Trigger"/> <!--设置Trigger中的值-->
</map>
</property>
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="trigger"/>
</list>
</property>
</bean>
我们将HelloWorldJob实现成JobDetailBean类,并配置触发器simpleTriggerBean
最后我们的测试类:
Java代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
package com.springQuartz.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String args[]){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
运行结果如下:
运行结果代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
2011-01-16 20:48:18,437 INFO - Starting Quartz Scheduler now
Hello World!
Previous Fire Time: null
Current Fire Time: Sun Jan 16 20:48:19 CST 2011
Next Fire Time: Sun Jan 16 20:48:29 CST 2011
Job Message From Trigger
Hello World!
Previous Fire Time: Sun Jan 16 20:48:19 CST 2011
Current Fire Time: Sun Jan 16 20:48:29 CST 2011
Next Fire Time: Sun Jan 16 20:48:39 CST 2011
Job Message From Trigger
下面说明几点:
1)首次触发是输出的Previous Fire Time为null
2)jobDataAsMap的说明:在HelloWorldJob.java中getMergedJobDataMap是JobDetail和Trigger上的JobDataMap的合并,两者数据如果冲突,则Trigger上的数据将覆盖JobDetail中的。运行结果也证明了,我们在Job中设置的值没有输出,而输出了"Job Message From Trigger"。
3)我们看到HelloWorldJob实现了Job接口,代码上依赖了Quartz的接口
下面我们讨论另外一种更普遍的,去除接口依赖的实现
主要的applicationContext.xml文件的配置
Xml代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
<bean id="jobService" class="com.springQuartz.service.JobServiceImpl">
</bean>
<bean id="invokeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="jobService" /> <!--目标Job-->
</property>
<property name="targetMethod">
<value>JobServiceImpl中的特定方法</value> <!--目标方法-->
</property>
<property name="concurrent">
<value>false</value> <!--设置是否同步-->
</property>
</bean>
<bean id="jobServiceCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="invokeJob" />
<property name="cronExpression" value="5/10 * * * * ?" />
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="jobServiceCronTrigger"/>
</list>
</property>
</bean>
1)首先我们配置具体的Job信息--JobServiceImpl,这个类可以不实现Quartz中的Job接口
2)最主要的MethodInvokingJobDetailFactoryBean,可以使得1)可行
3)相对于上面的例子,我们使用CronTriggerBean实现trigger,实现更灵活的时间配置
4)默认情况下,Quartz Jobs是无状态的,可能导致jobs之间互相的影响。如果你为相同的
第二个job将不会在第一个job完成之前开始。为了使得jobs不并发运行,设置
最近学习的东西记录下来,欢迎大家拍砖
而Spring很好地集成了Quartz,为企业级的任务调度提供了方便。
下面先看一个实现了Job接口的任务HelloWorldJob:
Java代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
package com.springQuartz.example;
import java.util.Map;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloWorldJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
Map properties = context.getMergedJobDataMap();
System.out.println("Hello World!");
System.out.println("Previous Fire Time: "+context.getPreviousFireTime());//上次触发任务的时间
System.out.println("Current Fire Time: "+context.getFireTime());//当然触发时间
System.out.println("Next Fire Time: "+context.getNextFireTime());//下次触发时间
System.out.println(properties.get("message"));
System.out.println();
}
}
这个Job输出"HelloWorld",同时输出上次、本次及下次触发的时间。
我们看一下在applicationContext.xml中的配置:
Xml代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
<bean id="job" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.springQuartz.example.HelloWorldJob"/>
<property name="jobDataAsMap">
<map>
<entry key="triggerMessage" value="Job Message In JobDetail"/> <!--设置JobDetail中的值-->
</map>
</property>
</bean>
<bean id="trigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="job"/> <!--触发的job引用-->
<property name="startDelay" value="1000"/> <!--设置延迟1秒后运行-->
<property name="repeatInterval" value="10000"/> <!--设置每10秒触发一次-->
<property name="jobDataAsMap">
<map>
<entry key="triggerMessage" value="Job Message From Trigger"/> <!--设置Trigger中的值-->
</map>
</property>
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="trigger"/>
</list>
</property>
</bean>
我们将HelloWorldJob实现成JobDetailBean类,并配置触发器simpleTriggerBean
最后我们的测试类:
Java代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
package com.springQuartz.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String args[]){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
运行结果如下:
运行结果代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
2011-01-16 20:48:18,437 INFO - Starting Quartz Scheduler now
Hello World!
Previous Fire Time: null
Current Fire Time: Sun Jan 16 20:48:19 CST 2011
Next Fire Time: Sun Jan 16 20:48:29 CST 2011
Job Message From Trigger
Hello World!
Previous Fire Time: Sun Jan 16 20:48:19 CST 2011
Current Fire Time: Sun Jan 16 20:48:29 CST 2011
Next Fire Time: Sun Jan 16 20:48:39 CST 2011
Job Message From Trigger
下面说明几点:
1)首次触发是输出的Previous Fire Time为null
2)jobDataAsMap的说明:在HelloWorldJob.java中getMergedJobDataMap是JobDetail和Trigger上的JobDataMap的合并,两者数据如果冲突,则Trigger上的数据将覆盖JobDetail中的。运行结果也证明了,我们在Job中设置的值没有输出,而输出了"Job Message From Trigger"。
3)我们看到HelloWorldJob实现了Job接口,代码上依赖了Quartz的接口
下面我们讨论另外一种更普遍的,去除接口依赖的实现
主要的applicationContext.xml文件的配置
Xml代码
![](http://xiaoye4188.iteye.com/images/icon_star.png)
<bean id="jobService" class="com.springQuartz.service.JobServiceImpl">
</bean>
<bean id="invokeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="jobService" /> <!--目标Job-->
</property>
<property name="targetMethod">
<value>JobServiceImpl中的特定方法</value> <!--目标方法-->
</property>
<property name="concurrent">
<value>false</value> <!--设置是否同步-->
</property>
</bean>
<bean id="jobServiceCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="invokeJob" />
<property name="cronExpression" value="5/10 * * * * ?" />
</bean>
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="jobServiceCronTrigger"/>
</list>
</property>
</bean>
1)首先我们配置具体的Job信息--JobServiceImpl,这个类可以不实现Quartz中的Job接口
2)最主要的MethodInvokingJobDetailFactoryBean,可以使得1)可行
3)相对于上面的例子,我们使用CronTriggerBean实现trigger,实现更灵活的时间配置
4)默认情况下,Quartz Jobs是无状态的,可能导致jobs之间互相的影响。如果你为相同的
JobDetail指定两个Trigger, 很可能当第一个job完成之前,第二个job就开始了。如果
JobDetail对象实现了
Stateful接口,就不会发生这样的事情。
第二个job将不会在第一个job完成之前开始。为了使得jobs不并发运行,设置
MethodInvokingJobDetailFactoryBean中的
concurrent标记为
false。
最近学习的东西记录下来,欢迎大家拍砖
![](http://xiaoye4188.iteye.com/images/smiles/icon_smile.gif)
相关文章推荐
- Java拆箱装箱
- Java注释@interface的用法【转】
- struts2取值方法
- java中将点替换成File.separator
- java--遇到NoSuchMethodError通用解决思路
- java.net.ConnectException: failed to connect to /10.0.2.2 (port 80): connect
- JAVA 计算地球上任意两点(经纬度)距离
- 2012年笔记-Struts2使用token标签防止重复提交
- Spring声明式事务配置管理方法
- java中包的学习
- MD5加密算法(java版)
- 关于IntelliJ IDEA 14控制台中文乱码问题
- Spring4新特性——泛型限定式依赖注入
- java自带线程池和队列详细讲解
- Java基础毕向东day04
- Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'o
- eclipse 中git解决冲突
- Java基础2
- MyEclipse+Struts+Spring+Hibernate 环境配置
- 。Java注意事项