论坛首页 Java企业应用论坛

关于Spirng Quartz定时触发器+源码示例!

浏览 13075 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-20   最后修改:2012-04-20

    最近实现了一个业务,刚好需要用到Spring 触发器,特写了一个Spring 触发器Demo供大家学习参考!

     Demo简单的实现了定时报时功能,通过Spring 触发器实现每分钟报一次时间!

Demo结构如下:



 运行结果如下:


 

简单解释一下Quartz:

    Quartz调度器为调度工作提供了更丰富的支持。和Java定时器一样,可以使用Quartz来每隔多少毫秒执行一个工作。但Quartz比Java Timer更先进之处在于它允许你调度一个工作在某个特定的时间或日期执行。关于Quartz的更多信息,可以访问Quartz位于 http://www.opensymphony.com/quartz的主页。


在简单介绍下创建触发器的步骤:

    首先需要创建一个工作类,这个类必须继承Spring的QuartzJobBean

package jobs;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import service.ITellingTheTimeService;


/**
 * @ProjectName:报时Demo   
 * @ClassName:TellingTheTimeJob   
 * @Description:   
 * @author:Sheep
 * @date:2012-4-19 下午03:58:11   
 * @Modifier: 
 * @Modify Date:  
 * @Modify Note:   
 * @version
 */
public class TellingTheTimeJob extends QuartzJobBean {
	
	private ITellingTheTimeService tellingTheTimeService = null;

	@Override
	protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
		//调用报时方法
		this.tellingTheTimeService.tellingTheTime();
	}

	public ITellingTheTimeService getTellingTheTimeService() {
		return tellingTheTimeService;
	}

	public void setTellingTheTimeService(
			ITellingTheTimeService tellingTheTimeService) {
		this.tellingTheTimeService = tellingTheTimeService;
	}
}

     QuartzJobBean是Quartz中与Java的TimerTask等价的类。它实现了org.quartz.Job接口。executeInternal()方法定义了当预定的时刻来临时应该执行哪些动作。


接着我们须在Sping配置文件中声明这个Job。

<!-- 配置一个Job -->
	<bean id="tellTheTimeJob" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass" value="jobs.TellingTheTimeJob"/>
		<property name="jobDataAsMap">
			<map>
				<entry key="tellingTheTimeService" value-ref="tellingTheTimeService"></entry>
			</map>
		</property>
	</bean>

    JobDetailBean 是Quartz的org.quartz.JobDetail的子类,它要求通过jobClass属性来设置一个Job对象。
    使用Quartz的JobDetail中的另一个特别之处是TellingTheTimeJob 的tellingTheTimeService 属性是间接设置的。JobDetail的jobDataAsMap属性接受一个java.util.Map,其中包含了需要设置给jobClass的各种 属性。在这里,这个map包含了一个指向tellingTheTimeService的引用,它的键值为tellingTheTimeService 。当JobDetailBean实例化时,它会将tellingTheTimeService注入到TellingTheTimeJob 的tellingTheTimeService属性中。


    一个Job定义好了,那么我们怎么来实现触发器来调用这个Job呢?接着我们需要在Sping配置触发器。

    Spring提供了两个触发器,SimpleTriggerBean和CronTriggerBean。

    我们现在看看SimpleTriggerBean是怎么配置的,如下:

<!-- 简单的触发器 -->
	<bean id="simpleTellTheTimeTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail">
			<ref bean="tellTheTimeJob" />
		</property>
		<!-- 以毫秒为单位,启动后一分钟触发 -->
		<property name="startDelay">
			<value>60000</value>
		</property>
		<!-- 每间隔一分钟触发一次 -->
		<property name="repeatInterval">
			<value>60000</value>
		</property>
	</bean>

    SimpleTriggerBean与ScheduledTimerTask类似。你可以用它来指定一个工作应该以怎样的频度运行,以及(可选地)在第一次运行工作之前应该等待多久。其中,jobDetail 属性告诉触发器调度哪个工作。

    我们再来看看CronTriggerBean是怎么配置的,如下:

<!-- 复杂的触发器 -->
	<bean id="complexTellTheTimeTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
		<property name="jobDetail">
			<ref bean="tellTheTimeJob"/>
		</property>
		<property name="cronExpression">
			<!-- 这里是重点,可以自定义表达式实现定时触发。以下含义是每分钟触发一次 -->
			<value>0 0/1 * * * ?</value>
		</property>
	</bean>

    和SimpleTriggerBean一样,jobDetail属性告诉触发器调度哪个工作。属性cronExpression告诉触发器何时触发。我们可以通过配置cronExpression属性的value值来实现赋值的触发逻辑。

    一个cron表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下:

1.秒(0–59)
2.分钟(0–59)
3.小时(0–23)
4.月份中的日期(1–31)
5.月份(1–12或JAN–DEC)
6.星期中的日期(1–7或SUN–SAT)
7.年份(1970–2099)

    每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的 日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。表7.1中显示了一些cron表达式的例子和它们的意义:

一些cron表达式的例子
表   达   式                 意     义
0 0 10,14,16 * * ?                     每天上午10点,下午2点和下午4点
0 0,15,30,45 * 1-10 * ?                每月前10天每隔15分钟
30 0 0 1 1 ? 2012                      在2012年1月1日午夜过30秒


   到了这里所需的一切都准备好了,那么如果启动这个触发器呢?我们需要在Sping XML如下配置:

<!-- Spring触发工厂 -->
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="complexTellTheTimeTrigger"/>
				<!-- ....下面可以继续添加其他触发器 -->
			</list>
		</property>
	</bean>

   Spring的SchedulerFactoryBean 是Quartz中与TimerFactoryBean等价的类。属性triggers接受一组触发器。因此只需简单地装配一个包含complexTellTheTimeTrigger的一个引用的即可。


    这里就实现了每分钟报一次时间的业务需求,下面附上源码(包含了所需的Jar包)供大家学习参考:

http://resp.iteye.com/blog/1490575

 

   发表时间:2012-04-21  
<task:annotation-driven  />

@Scheduled(cron = "0 0/1 * * * ?")
work(){

}
0 请登录后投票
   发表时间:2012-04-21  
spring3.1已经不用quartz了,有spring自己实现的定时任务。
根本不用这么麻烦。
0 请登录后投票
   发表时间:2012-04-21  
怎么报错了?
严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContextException
0 请登录后投票
   发表时间:2012-04-22  
spring+quartz想动态持久化job的话...就要十分小心了
0 请登录后投票
   发表时间:2012-04-22  
slertname 写道
spring3.1已经不用quartz了,有spring自己实现的定时任务。
根本不用这么麻烦。

那spring3.1用什么来实现? 愿听其详,呵呵,谢谢。
0 请登录后投票
   发表时间:2012-04-23  
shmily2038 写道
slertname 写道
spring3.1已经不用quartz了,有spring自己实现的定时任务。
根本不用这么麻烦。

那spring3.1用什么来实现? 愿听其详,呵呵,谢谢。

同问,谢谢
0 请登录后投票
   发表时间:2012-04-23  
dailindl 写道
shmily2038 写道
slertname 写道
spring3.1已经不用quartz了,有spring自己实现的定时任务。
根本不用这么麻烦。

那spring3.1用什么来实现? 愿听其详,呵呵,谢谢。

同问,谢谢


请教下,不用quartz如果用Spring自己实现定时任务?
0 请登录后投票
   发表时间:2012-04-23  
我想问一下如果电脑是12小时制的 我要每天早上0点10s定时怎么弄
0 请登录后投票
   发表时间:2012-04-23  
aa87963014 写道
<task:annotation-driven  />

@Scheduled(cron = "0 0/1 * * * ?")
work(){

}

确实方便好多 系统时间是12小时的 应该怎么设置 零点执行任务啊
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics