日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【Spring学习】spring提供的三种定时任务

發布時間:2024/4/14 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Spring学习】spring提供的三种定时任务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在spring中我們有三種不同的定時任務:基于Quartz的定時機制、基于Timer的定時機制、基于Executor的定時機制。

1、基于Quartz的定時任務機制

下面詳細解釋這個類圖中涉及的關鍵類及其使用場景

1.1. SchedulerFactoryBean

這是Spring中基于Quartz的定時機制入口,只要Spring容器裝載了這個類,Quartz定時機制就會啟動,并加載定義在這個類中的所有trigger

1.2. CronTriggerBean

實現了Trigger接口,基于Cron表達式的觸發器。這種觸發器的好處是表達式與linux下的crontab一致,能夠滿足非常復雜的定時需求,也容易配置

1.3. MethodInvokingJobDetailFactoryBean

Spring提供的一個不錯的JobDetail包裝工具,能夠包裝任何bean,并執行類中指定的任何stati或非static的方法,避免強制要求bean去實現某接口或繼承某基礎類。

Spring配置實例:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><bean id="jobDetail_1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject"><ref bean="TSupeviseServiceImpl" /></property><property name="targetMethod"><value>processTInterface</value><!-- 處理數據到業務督辦表T_Interface中 --></property></bean><bean id="cronTrigger_1" class="org.springframework.scheduling.quartz.CronTriggerBean"><property name="jobDetail"><ref bean="jobDetail_1" /></property><property name="cronExpression"><value>0 0 10 * * ? *</value><!-- 每天上午10點執行 --></property></bean><bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref local="cronTrigger_1" /></list></property></bean></beans>

1.4. SimpleTriggerBean

該類也實現了Trigger接口,基于配置的定時調度。這個觸發器的優點在于很容易配置一個簡單的定時調度策略

Spring配置范例:

<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.5. JobDetailBean

JobDetail類的簡單擴展,能夠包裝一個繼承自QuartzJobBean的普通Bean,使之成為定時運行的Job..缺點是包裝的Bean必須繼承自一個指定的類,通用性不強,對普通Job的侵入性過強,不推薦使用。

1.6. 關于TriggerListener和JobListener

Quartz中提供了類似WebWork的攔截器的功能,系統執行任務前或任務執行完畢后,都會檢查是否有對應的Listener需要被執行,這種AOP的思想為我們帶來了靈活的業務需求實現方式。
例如現在有一個簡單的業務要求:任務執行前先判斷當前服務器是否為task服務器,不是則不執行任務。對于這種業務需求,我們可以簡單的實現一個 TriggerListener,并將其插入SchedulerFactoryBean的globalTriggerListeners中,這樣所有的 job在執行前后都會調用TriggerListener中對應的方法。

代碼范例:

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;} }

quartz表達式解析

2、基于Timer的定時機制

下面詳細解釋這個類圖中涉及的關鍵類及其使用場景

2.1. TimerFactoryBean

這個類非常類似Quartz中的SchedulerFactoryBean,是基于Timer的定時機制的入口,Spring容器裝載此類后會自動開始定時器。

2.2. ScheduledTimerTask

類似于Quartz中的Trigger的SimpleTriggerBean實現,任務是在設定的時間觸發并執行配置的任務,特點是配置簡單、明了,使用于簡單的任務觸發邏輯。

2.3. TimerTask抽象類

普通task實現必須要繼承的父類,主要包含一個run()的方法,類似Quartz中的QuartzJobBean,對應用侵入性較強,也不推薦使用。

2.4. MethodInvokingTimerTaskFactoryBean

類似Quartz中的MethodInvokingJobDetailFactoryBean,用于封裝任何bean,并可以執行bean中的任意方法,不再復述。

簡單實例:

MyTask.java

package com.lmb.springstudy.schedule.timer;public class MyTask {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void run() {System.out.println("Run this task: " + name + ".");}}

Spring-timer.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"default-lazy-init="true"><bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean" lazy-init="false"><property name="scheduledTimerTasks"><list><ref local="scheduledTask1"/><ref local="scheduledTask2"/></list></property></bean><bean id="scheduledTask1" class="org.springframework.scheduling.timer.ScheduledTimerTask"><property name="delay" value="0" /><property name="period" value="10000" /><property name="timerTask"><ref bean="methodInvokingTask1"/></property></bean><bean id="scheduledTask2" class="org.springframework.scheduling.timer.ScheduledTimerTask"><property name="delay" value="0" /><property name="period" value="10000" /><property name="timerTask"><ref bean="methodInvokingTask2"/></property></bean><bean id="methodInvokingTask1" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean"><property name="targetObject" ref="myTask1"/><property name="targetMethod" value="run"/></bean><bean id="methodInvokingTask2" class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean"><property name="targetObject" ref="myTask2"/><property name="targetMethod" value="run"/></bean><bean id="myTask1" class="org.garbagecan.springstudy.schedule.timer.MyTask"><property name="name" value="task1"/></bean><bean id="myTask2" class="org.garbagecan.springstudy.schedule.timer.MyTask"><property name="name" value="task2"/></bean> </beans>

原理解析:

  • 定義了兩個task,task1和task2;
  • 利用spring提供的MethodInvokingTimerTaskFactoryBean類來實現來實現對對task類和方法的聲明,聲明目標對象和方法,從而使spring知道要運行那個類的那個方法;
  • 利用ScheduledTimerTask類來配置每個task的啟動時間延時,每次啟動之間的間隔,當然還有最重要的是需要運行那個對象,這里使用的上面提到的MethodInvokingTimerTaskFactoryBean類的實例;
  • 最后定義了一個TimerFactoryBean類,并且把ScheduledTimerTask類的實例作為需要調度的task;
  • Test.java

    package lmb.springstudy.schedule.timer;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) throws Exception {new ClassPathXmlApplicationContext("/com/lmb/springstudy/schedule/timer/spring-timer.xml");} }

    Test測試類運行結果:兩個task都會啟動,并且都以同樣的10s作為每次運行的時間間隔。

    3、基于Executor的定時機制

    這種定時機制與上面兩種定時機制沒有太大區別,特別是在配置和實現功能上,不同的是它的核心是基于ScheduledExecutorService(ScheduledThreadPoolExecutor是默認實現),一種JDK5.0中提供的基于線程的并發機制。關于Executor的詳細內容請參看博主的另一篇文章。

    如果需要簡單的定時器可以選用基于Timer的定時機制,如果需要較復雜的定時器可以選用基于Quartz的定時機制,如果我們要用到線程池來處理異步任務,我們可以選用基于Executor的定時機制,雖然只是任務實現中用到線程池,畢竟也是一脈相承的,當然也可以用Quartz的定時器+基于Executor的任務線程池,完全沒有任何沖突的。

    有關Executor的詳細內容,請參看本人的以下文章:http://blog.csdn.net/lmb55/article/details/50555309

    總結

    以上是生活随笔為你收集整理的【Spring学习】spring提供的三种定时任务的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。