前言
以前每次看定时任务,总是感觉怪怪的,因为每一种的写法都不一样,感觉没有套路,这不好.
其实,spring Task和Quartz都是定时任务的实现方式,甚至java中的timer也是定时任务的实现方式(只是没人用,个人没用过)。插一嘴,spring task实际上是一种轻量级的quartz,实现的方式比quartz简单很多
quartz:
- 默认多线程异步执行
- 能被集群实例化,支持分布式部署
- 使用JobStoreCMT(JDBCJobStore的子类),Quartz 能参与JTA事务;Quartz 能管理JTA事务(开始和提交)在执行任务之间,这样,任务做的事就可以发生在JTA事务里。
- 多个任务时,任务之间没有直接影响,多任务执行的快慢取决于CPU的性能
- 需要手动在xml中设置jobs(先配置job,之后为job设置特定trigger,最后将trigger在调度器中注册即可)
- 需要引入quartz的jar包
- 对异常的处理:Quartz的某次执行任务过程中抛出异常,不影响下一次任务的执行,当下一次执行时间到来时,定时器会再次执行任务。
- 任务类的对象:Quartz每次执行都创建一个新的任务类对象。
实例:以下链接,是我在gitHub上上传的可用代码,包括测试代码
个人gitHub链接
支持git下载(SSH链接):
git@github.com:LittleCadet/ftp.git
这里贴出代码中xml的部分配置
<!-- 先配置job2-->
<bean name="scanDirectoryJobBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scanDirectory"/>
<property name="targetMethod" value="scan"/>
<property name="concurrent" value="false"/>
</bean>
<!--Quartz的定时任务2 的触发器 -->
<bean id="scanDirectoryrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="scanDirectoryJobBean">
</property>
<property name="cronExpression" value="${download.cronExpression}" />
</bean>
<!-- 中心调度器-->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="no">
<property name="triggers">
<list>
<!-- 执行定时下载服务器上文件-->
<!--<ref bean="ftpDownloadTrigger" />-->
<!-- 执行定时扫描服务器上的文件,一旦变动即可触发下载任务-->
<ref bean="scanDirectoryrigger" />
</list>
</property>
</bean>
task
- 默认单线程同步执行
- 支持注解(个人建议:不要把表达式通过注解的方式实现:不利于维护)
- 多个任务时,一个任务执行完毕以后才能执行下一个任务(如果当前任务执行时间过长,那么下一个任务可能无法及时运行,即会有阻塞现象发生),如果希望并发运行,需要配置线程池
- 对异常的处理:SpringTask不同,一旦某个任务在执行过程中抛出异常,则整个定时器生命周期就结束,以后永远不会再执行定时器任务。
- 任务类的对象:SpringTask则每次使用同一个任务类对象。