- 浏览: 1499319 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
定时任务的需求在众多应用系统中广泛存在,在Spring中,我们可以使用三种不同的定时机制,下面一一描述并加以比较
1. 基于Quartz的定时机制
下面详细解释这个类图中涉及的关键类及其使用场景
1.1. SchedulerFactoryBean
这是Spring中基于Quartz的定时机制入口,只要Spring容器装载了这个类,Quartz定时机制就会启动,并加载定义在这个类中的所有trigger
Spring配置范例:
view plaincopy to clipboardprint?
<bean id="sfb" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 添加触发器 -->
<property name="triggers">
<list>
<ref local="appSubscTrigger" />
</list>
</property>
<!-- 添加listener -->
<property name="globalTriggerListeners">
<list>
<ref local="myTaskTriggerListener" />
</list>
</property>
</bean>
<bean id="sfb" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 添加触发器 -->
<property name="triggers">
<list>
<ref local="appSubscTrigger" />
</list>
</property>
<!-- 添加listener -->
<property name="globalTriggerListeners">
<list>
<ref local="myTaskTriggerListener" />
</list>
</property>
</bean>
1.2. CronTriggerBean
实现了Trigger接口,基于Cron表达式的触发器
这种触发器的好处是表达式与linux下的crontab一致,能够满足非常复杂的定时需求,也容易配置
Spring配置范例:
view plaincopy to clipboardprint?
<bean id="notifyTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="notifyJobDetail" />
<property name="cronExpression" value="${notify_trigger_cron_expression}" />
</bean>
<bean id="notifyTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="notifyJobDetail" />
<property name="cronExpression" value="${notify_trigger_cron_expression}" />
</bean>
1.3. SimpleTriggerBean
该类也实现了Trigger接口,基于配置的定时调度
这个触发器的优点在于很容易配置一个简单的定时调度策略
Spring配置范例:
view plaincopy to clipboardprint?
<bean id="simpleReportTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="reportJob"/>
</property>
<property name="startDelay">
<value>3600000</value>
</property>
<property name="repeatInterval">
<value>86400000</value>
</property>
</bean>
<bean id="simpleReportTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="reportJob"/>
</property>
<property name="startDelay">
<value>3600000</value>
</property>
<property name="repeatInterval">
<value>86400000</value>
</property>
</bean>
1.4. JobDetailBean
JobDetail类的简单扩展,能够包装一个继承自QuartzJobBean的普通Bean,使之成为定时运行的Job
缺点是包装的Bean必须继承自一个指定的类,通用性不强,对普通Job的侵入性过强,不推荐使用
1.5. MethodInvokingJobDetailFactoryBean
Spring提供的一个不错的JobDetail包装工具,能够包装任何bean,并执行类中指定的任何stati或非static的方法,避免强制要求bean去实现某接口或继承某基础类
Spring配置范例:
view plaincopy to clipboardprint?
<bean id="notifyJobDetail" parent="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="notifyServerHandler" />
<property name="targetMethod" value="execute" />
</bean>
<bean id="notifyJobDetail" parent="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="notifyServerHandler" />
<property name="targetMethod" value="execute" />
</bean>
1.6. 关于TriggerListener和JobListener
Quartz中提供了类似WebWork的拦截器的功能,系统执行任务前或任务执行完毕后,都会检查是否有对应的Listener需要被执行,这种AOP的思想为我们带来了灵活的业务需求实现方式。
例如现在有一个简单的业务要求:任务执行前先判断当前服务器是否为task服务器,不是则不执行任务。对于这种业务需求,我们可以简单的实现一个TriggerListener,并将其插入SchedulerFactoryBean的globalTriggerListeners中,这样所有的job在执行前后都会调用TriggerListener中对应的方法。
代码范例:
view plaincopy to clipboardprint?
public class MyTaskTriggerListener implements TriggerListener {
protected static final Log logger = LogFactory.getLog(MyTaskTriggerListener.class);
/**
* 需要运行task任务的机器列表
*/
private String taskServers;
public String getName() {
return "MyTaskTriggerListener";
}
public void triggerComplete(Trigger arg0, JobExecutionContext arg1, int arg2) {
}
public void triggerFired(Trigger arg0, JobExecutionContext arg1) {
}
public void triggerMisfired(Trigger arg0) {
}
/**
* 判断当前服务器是否为task服务器,来决定是否执行task
* @return
*/
public boolean vetoJobExecution(Trigger arg0, JobExecutionContext arg1) {
String serverName;
try {
serverName = InetAddress.getLocalHost().getHostName();//获取主机名
} catch (UnknownHostException e) {
e.printStackTrace();
return true;
}
if (taskServers.indexOf(serverName) > -1) {
if (logger.isInfoEnabled()) {
logger.info("this is a task server, job will be executed");
}
return false;
} else {
if (logger.isInfoEnabled()) {
logger.info("this is not a task server, job will be vetoed");
}
return true;
}
}
public String getTaskServers() {
return taskServers;
}
public void setTaskServers(String taskServers) {
this.taskServers = taskServers;
}
}
public class MyTaskTriggerListener implements TriggerListener {
protected static final Log logger = LogFactory.getLog(MyTaskTriggerListener.class);
/**
* 需要运行task任务的机器列表
*/
private String taskServers;
public String getName() {
return "MyTaskTriggerListener";
}
public void triggerComplete(Trigger arg0, JobExecutionContext arg1, int arg2) {
}
public void triggerFired(Trigger arg0, JobExecutionContext arg1) {
}
public void triggerMisfired(Trigger arg0) {
}
/**
* 判断当前服务器是否为task服务器,来决定是否执行task
* @return
*/
public boolean vetoJobExecution(Trigger arg0, JobExecutionContext arg1) {
String serverName;
try {
serverName = InetAddress.getLocalHost().getHostName();//获取主机名
} catch (UnknownHostException e) {
e.printStackTrace();
return true;
}
if (taskServers.indexOf(serverName) > -1) {
if (logger.isInfoEnabled()) {
logger.info("this is a task server, job will be executed");
}
return false;
} else {
if (logger.isInfoEnabled()) {
logger.info("this is not a task server, job will be vetoed");
}
return true;
}
}
public String getTaskServers() {
return taskServers;
}
public void setTaskServers(String taskServers) {
this.taskServers = taskServers;
}
}
2. 基于Timer的定时机制
JDK提供了基础的定时类:Timer,在这个类的基础上,Spring提供了一套简单的定时机制
下面详细解释这个类图中涉及的关键类及其使用场景
2.1. TimerFactoryBean
这个类非常类似Quartz中的SchedulerFactoryBean,是基于Timer的定时机制的入口,Spring容器装载此类后会自动开始定时器
Spring配置范例:
view plaincopy to clipboardprint?
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="scheduledTask" />
</list>
</property>
</bean>
2.2. ScheduledTimerTask
类似于Quartz中的Trigger的SimpleTriggerBean实现,任务是在设定的时间触发并执行配置的任务,特点是配置简单、明了,使用于简单的任务触发逻辑
Spring配置范例:
+ expand sourceview plaincopy to clipboardprint?
<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.ScheduledTimerTask”>
<property name=”timerTask”>
<ref bean =”reportTimerTask”/>
</property>
<property name=”period”>
<value>86400000</value>
</property>
</bean>
<bean id=”scheduledReportTask” class=”org.springframework.scheduling.timer.ScheduledTimerTask”>
<property name=”timerTask”>
<ref bean =”reportTimerTask”/>
</property>
<property name=”period”>
<value>86400000</value>
</property>
</bean>
2.3. TimerTask抽象类
普通task实现必须要继承的父类,主要包含一个run()的方法,类似Quartz中的QuartzJobBean,对应用侵入性较强,也不推荐使用
2.4. MethodInvokingTimerTaskFactoryBean
类似Quartz中的MethodInvokingJobDetailFactoryBean,用于封装任何bean,并可以执行bean中的任意方法,不再复述
3. 基于Executor的定时机制
这种定时机制与上面两种定时机制没有太大区别,特别是在配置和实现功能上,不同的是它的核心是基于ScheduledExecutorService(ScheduledThreadPoolExecutor是默认实现),一种JDK5.0中提供的基于线程的并发机制,关于JDK5中的线程池的概念及其一些深入分析,请参考老唐的博客:http://blog.csdn.net/sfdev/archive/2008/12/30/3648457.aspx 这里不再复述
4. 三种定时机制的比较和案例分析
看完了这三种定时机制,各有各的优劣,不同场景下我们应该灵活选择不同的定时机制。总的来说,如果我们需要简单的定时器,我们可以选用基于timer的定时器,如果定时规则较为复杂,我们可以选用基于Quartz的定时器,如果我们要用到线程池来处理异步任务,我们可以选用基于Executor的定时机制,虽然只是任务实现中用到线程池,毕竟也是一脉相承的,当然也可以用Quartz的定时器+基于Executor的任务线程池,完全没有任何冲突的。
说这么多,还是比较抽象,不如我们来分析一下老唐的Notify系统来加深对Spring定时机制的了解(详细设计参考最近一期的程序员杂志)。
在老唐的Notify系统中,完全使用了基于JDK5.0中的Executor的定时机制,即由一个ScheduledExecutorFactoryBean触发系统的每隔2分钟运行一个单线程的任务,在这个任务中,执行完各种机制检查和配置策略后,将要执行的Notify任务放入一个已配置好的线程池,并由线程池指定线程来完成Notify的任务。
在最近一期的项目中,我们将task移植到了apps,Notify系统也同时被移植过来了,为了统一所有的task,我们将以前task中基于timer、Quartz和Executor的各种任务统一改为基于Quartz的调度。在这个过程中,Notify系统的基于Executor的定时机制也被改为基于Quartz的定时机制,过程非常顺利。基于这次移植项目,可以说这三种定时机制是非常容易互换的,并且通用性比较强,只需要简单的配置即可。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/52rainbow/archive/2009/03/19/4004206.aspx
http://book.51cto.com/art/200909/149346.htm
相关推荐
比较这三种定时任务机制: - **Quartz** 适合于大型项目,具有高度可定制性,能够处理复杂的调度需求,但配置相对繁琐。 - **`@Scheduled`** 更加轻量级,适用于简单定时任务,易于理解和使用,但在大型项目中可能...
Spring 框架提供了多种定时任务机制来满足不同复杂度的应用需求。在这篇文章中,我们将深入探讨其中的三种主要机制:基于Quartz的定时任务、Spring的Scheduled任务以及基于Java的TimerTask。每种机制都有其特点和...
下面我们将深入探讨Spring定时任务所需的相关jar包以及它们的功能。 首先,Spring框架的核心jar包`spring-context.jar`是必不可少的。这个jar包包含了Spring的核心功能,如依赖注入(Dependency Injection,DI)、...
Spring Boot作为一个流行的微服务开发框架,为开发者提供了一种简单而强大的方式来处理定时任务——即通过使用`@Scheduled`注解。本文将详细介绍`@Scheduled`注解的工作原理、配置方法以及如何在实际项目中运用它来...
在Spring框架2.5版本中,提供了强大的定时任务管理功能,支持多种方式来实现定时任务的调度与执行。这为开发人员提供了一个灵活且易于集成的解决方案,使得应用程序能够按照预定的时间间隔或特定时间点执行某些任务...
在 Spring 中,动态定时任务是一种允许用户在不重启服务的情况下,自由调整任务执行时间的机制。这种功能通常通过集成第三方定时任务框架,如 Quartz,来实现。Quartz 是一个功能强大的开源作业调度框架,能够帮助...
Spring 的定时任务机制基于Java 5 的定时器功能,并通过`@Scheduled`注解实现。此特性允许开发者以声明式的方式定义需要周期性执行的任务,而无需编写额外的线程或定时器代码。这种机制简化了开发过程,使得开发者...
其中,前三种方案均不支持集群环境下的定时任务,而第四种方案即Spring结合Quartz支持数据库的方式,能够很好地解决上述问题。 ### Quartz框架简介 Quartz是一款完全由Java编写的开源作业调度框架。它不仅支持简单...
主要内容涵盖SpringBatch框架的基本组成要素(JobLauncher、Job、Step、JobRepository)、Job与Step创建方法(包括Tasklet与chunk的实现方式)、任务监听机制以及简易的任务调度实现。针对初学者提供了具体的案例,...
让我们详细了解一下Spring中的定时任务机制及其相关的库。 Spring提供了一个名为`Spring Task`的模块,也称为Spring调度器,它允许我们在应用程序中执行定时任务。这个模块基于`java.util.concurrent....
SpringBoot提供了`@Scheduled`注解,可以用来创建定时任务。例如,我们可以定义一个方法检查未确认的消息,并在必要时进行重试。这可以防止因临时故障导致的消息丢失。同时,我们还可以设置超时策略,如果消息在一定...
在Spring框架中,远程调用、定时任务和邮件发送是企业级应用中常见的功能需求。Spring提供了丰富的支持,使得开发者能够轻松地实现这些功能。在"spring技术手册demo2"中,我们将探讨如何利用RMI(Remote Method ...
Spring的Task模块和Quartz插件可以实现定时任务的调度。 23. **Spring Cloud是什么?** Spring Cloud是一系列工具的集合,用于简化微服务架构的构建,提供了服务发现、配置中心、负载均衡、熔断机制等功能。 24....
Spring定时器主要支持两种方式来实现定时任务:基于注解的方式和基于Quartz集成的方式。 #### 二、Spring定时器的实现原理 ##### 2.1 基于注解的定时任务 Spring 3.0引入了`@Scheduled`注解,它可以直接添加到...
在Java环境中,Spring Quartz使得我们可以方便地管理和配置定时任务,而无需深入理解Quartz的复杂配置。 首先,我们来看一下提供的jar包: 1. `spring.jar`:这是Spring框架的核心库,包含了Spring的核心组件,如...
- **定时任务**:Spring支持基于cron表达式的定时任务,方便开发者执行周期性的后台任务。 - **异步任务**:此外,Spring还支持异步任务的执行,以提高应用程序的响应能力。 #### 12. 使用Spring Remoting - **远程...
10. **Spring Batch**:用于处理批量和定时任务,支持复杂的批处理作业管理和重试机制。 11. **Spring Test**:提供了一套强大的测试工具,包括单元测试、集成测试和端到端测试,确保代码的质量和稳定性。 这个...
Spring不仅可以用来开发简单的Java应用程序,还可以轻松地与各种企业服务集成,例如数据库连接池、邮件服务、定时任务等。 #### 4.1 数据源配置 Spring提供了多种方式来配置数据源,比如基于XML的配置或者注解驱动...
- **定时任务**:介绍如何使用 Spring 进行定时任务的调度。 - **任务执行器**:讲解 Spring 提供的任务执行器(TaskExecutor)接口及其实现。 #### 十六、Spring 远程调用(第16章) - **远程调用概念**:解释...