Spring提供的三种定时任务机制及其比较

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Spring提供的三种定时任务机制及其比较定时任务的需求在众多应用系统中广泛存在,在Spring中,我们可以使用三种不同的定时机制,下面一一描述并加以比较1.基于Quartz的定时机制下面详细解释这个类图中涉及的关键类及其使用场景1.1.SchedulerFactoryBean这是Spring中基于Quartz的定时机制入口,只要Spring容器装载了这个类,Quartz定时机制就会启动,并加载定义在这个类中的所有triggerSpring配置范例:[xhtml]viewplaincopy1.beanid=sfbclass=org.springframework.scheduling.quartz.SchedulerFactoryBean2.!--添加触发器--3.propertyname=triggers4.list5.reflocal=appSubscTrigger/6./list7./property8.9.!--添加listener--10.propertyname=globalTriggerListeners11.list12.reflocal=myTaskTriggerListener/13./list14./property15./bean1.2.CronTriggerBean实现了Trigger接口,基于Cron表达式的触发器这种触发器的好处是表达式与linux下的crontab一致,能够满足非常复杂的定时需求,也容易配置Spring配置范例:[xhtml]viewplaincopy1.beanid=notifyTriggerclass=org.springframework.scheduling.quartz.CronTriggerBean2.propertyname=jobDetailref=notifyJobDetail/3.propertyname=cronExpressionvalue=${notify_trigger_cron_expression}/4./bean1.3.SimpleTriggerBean该类也实现了Trigger接口,基于配置的定时调度这个触发器的优点在于很容易配置一个简单的定时调度策略Spring配置范例:[xhtml]viewplaincopy1.beanid=simpleReportTriggerclass=org.springframework.scheduling.quartz.SimpleTriggerBean2.propertyname=jobDetail3.refbean=reportJob/4./property5.propertyname=startDelay6.value3600000/value7./property8.propertyname=repeatInterval9.value86400000/value10./property11./bean1.4.JobDetailBeanJobDetail类的简单扩展,能够包装一个继承自QuartzJobBean的普通Bean,使之成为定时运行的Job缺点是包装的Bean必须继承自一个指定的类,通用性不强,对普通Job的侵入性过强,不推荐使用1.5.MethodInvokingJobDetailFactoryBeanSpring提供的一个不错的JobDetail包装工具,能够包装任何bean,并执行类中指定的任何stati或非static的方法,避免强制要求bean去实现某接口或继承某基础类Spring配置范例:[xhtml]viewplaincopy1.beanid=notifyJobDetailparent=org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean2.propertyname=targetObjectref=notifyServerHandler/3.propertyname=targetMethodvalue=execute/4./bean1.6.关于TriggerListener和JobListenerQuartz中提供了类似WebWork的拦截器的功能,系统执行任务前或任务执行完毕后,都会检查是否有对应的Listener需要被执行,这种AOP的思想为我们带来了灵活的业务需求实现方式。例如现在有一个简单的业务要求:任务执行前先判断当前服务器是否为task服务器,不是则不执行任务。对于这种业务需求,我们可以简单的实现一个TriggerListener,并将其插入SchedulerFactoryBean的globalTriggerListeners中,这样所有的job在执行前后都会调用TriggerListener中对应的方法。代码范例:[java]viewplaincopy1.publicclassMyTaskTriggerListenerimplementsTriggerListener{2.protectedstaticfinalLoglogger=LogFactory.getLog(MyTaskTriggerListener.class);3.4./**5.*需要运行task任务的机器列表6.*/7.privateStringtaskServers;8.9.publicStringgetName(){10.returnMyTaskTriggerListener;11.}12.13.publicvoidtriggerComplete(Triggerarg0,JobExecutionContextarg1,intarg2){14.}15.16.publicvoidtriggerFired(Triggerarg0,JobExecutionContextarg1){17.}18.19.publicvoidtriggerMisfired(Triggerarg0){20.}21.22./**23.*判断当前服务器是否为task服务器,来决定是否执行task24.*@return25.*/26.publicbooleanvetoJobExecution(Triggerarg0,JobExecutionContextarg1){27.StringserverName;28.try{29.serverName=InetAddress.getLocalHost().getHostName();//获取主机名30.}catch(UnknownHostExceptione){31.e.printStackTrace();32.returntrue;33.}34.if(taskServers.indexOf(serverName)-1){35.if(logger.isInfoEnabled()){36.logger.info(thisisataskserver,jobwillbeexecuted);37.}38.returnfalse;39.}else{40.if(logger.isInfoEnabled()){41.logger.info(thisisnotataskserver,jobwillbevetoed);42.}43.returntrue;44.}45.}46.47.publicStringgetTaskServers(){48.returntaskServers;49.}50.51.publicvoidsetTaskServers(StringtaskServers){52.this.taskServers=taskServers;53.}54.}2.基于Timer的定时机制JDK提供了基础的定时类:Timer,在这个类的基础上,Spring提供了一套简单的定时机制下面详细解释这个类图中涉及的关键类及其使用场景2.1.TimerFactoryBean这个类非常类似Quartz中的SchedulerFactoryBean,是基于Timer的定时机制的入口,Spring容器装载此类后会自动开始定时器Spring配置范例:[xhtml]viewplaincopy1.beanid=timerFactoryclass=org.springframework.scheduling.timer.TimerFactoryBean2.propertyname=scheduledTimerTasks3.list4.refbean=scheduledTask/5./list6./property7./bean2.2.ScheduledTimerTask类似于Quartz中的Trigger的SimpleTriggerBean实现,任务是在设定的时间触发并执行配置的任务,特点是配置简单、明了,使用于简单的任务触发逻辑Spring配置范例:[xhtml]viewplaincopy1.beanid=”scheduledReportTask”class=”org.springframework.scheduling.timer.ScheduledTimerTask”2.propertyname=”timerTask”3.refbean=”reportTimerTask”/4./property5.propertyname=”period”6.value86400000/value7./property8./bean2.3.TimerTask抽象类普通task实现必须要继承的父类,主要包含一个run()的方法,类似Quartz中的QuartzJobBean,对应用侵入性较强,也不推荐使用2.4.MethodInvokingTimerTaskFactoryBean类似Quartz中的MethodInvokingJobDetailFactoryBean,用于封装任何bean,并可以执行bean中的任意方法,不再复述3.基于Executor的定时机制这种定时机制与上面两种定时机制没有太大区别,特别是在配置和实现功能上,不同的是它的核心是基于ScheduledExecutorService(ScheduledThreadPoolExecutor是默认实现),一种JDK5.0中提供的基于线程的并发机制,关于JDK5中的线程池的概念及其一些深入分析,请参考老唐的博客:这里不再复述4.三种定时机制的比较和案例分析看完了这三种定时机制,各有各的优劣,不同场景下我们应该灵活选择不同的定时机制。总的来说,如果我们需要简单的定时器,我们可以选用基于timer的定时器,如果定时规则较为复杂,我们可以选用基于Quartz的定时器,如果我们要用到线程池来处理异步任务,我们可以选用基于Executor的定时机制,虽然只是任务实现中用到线程池,毕竟也是一脉相承的,当然也可以用Quartz的定时器+基于Executor的任务线程池,完全没有任何冲突的。说这么多,还是比较抽象,不如我们来分析一下老唐的Notify系统来加深对Spring定时机制的了解(详细设计参考最近一期的程序员杂志)。在老唐的Notify系统中,完全使用了基于JDK5.0中的Executor的定时机制,即由一个ScheduledExecutorFactoryBean触发系统的每隔2分钟运行一个单线程的任务,在这个任务中,执行完各种机制检查和配置策略后,将要执行的Notify任务放入一个已配置好的线程池,并由线程池指定线程来完成Notify的任务。在最近一期的项目中,我们将task移植到了apps,Notify系统也同时被移植过来了,为了统一所有的task,我们将以前tas

1 / 10
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功