A. spring中的定時器和jdk自帶的定時器有什麼區別
今天我介紹一下spring的定時器功能,它不僅實現起來方便,功能強大,而且在web開發時正好配合spring框架使用。
spring支持jdk內置的Timer類和Quartz Scheler
?
介紹spring的定時器,當然要先介紹配置文件applicationContext.xml了。
?
<bean name="job" class="org.springframework.scheling.quartz.JobDetailBean">
<property name="jobClass">
<value>jaoso.news.web.action.JobAction</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="timeout">
<value>10</value>
</entry>
</map>
</property>
</bean>
?
說明:org.springframework.scheling.quartz.JobDetailBean是spring對你的類進行調度的代理,在jobClass中要指定你的任務類(com.yangsq.web.action.JobAction),在jobDataAsMap中向你的任務類中注入一些信息,當然也可以reference一個,不要忘記在你的任務里加入這些屬性及set方法(有些羅嗦)。
timeout屬性設定了當伺服器啟動後過10秒鍾首次調用你的JobAction。
?
<bean id="cronTrigger" class="org.springframework.scheling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="job"/>
</property>
<property name="cronExpression">
<value>0 0/2 * * * ?</value>
</property>
</bean>
?
說明:org.springframework.scheling.quartz.CronTriggerBean是spring提供的觸發器,在這個觸發器中設定了要觸發的job(jobDetail屬性設定了先前定義的bean),同時設定了觸發時間(cronExpression)---每隔兩分鍾(0 0/2 * * * ?),這個的設定方式最後會說明。
?
<bean class="org.springframework.scheling.quartz.SchelerFactoryBean">
<property name="triggers">
<list>
<ref local="cronTrigger"/>
</list>
</property>
</bean>
?
說明:org.springframework.scheling.quartz.SchelerFactoryBean這是一個spring的工廠bean,在他的triggers屬性列表中加入剛才定義的觸發器,這里可以定義多個觸發器(list嘛)。
?
好了,配置文件就介紹完了,該介紹com.yangsq.web.action.JobAction類了,
?
引入包:
說明:QuartzJobBean是spring自帶的,把spring的jar包加入就行了,但是前兩個包要去下了,呵呵,google吧。
?
?
當然要繼承QuartzJobBean了,但是光extends不行,必須要重載他的executeInternal方法
B. java spring quartz 動態定時器
DELPHI這邊的連接並不難。
你可以使用DBExpress進行連接,效率高、直接,使用DELHPI提供的引擎。
其它的方式,你可能要安裝相應的驅動(數據客戶端程序通常包括驅動)。
要保障,你的服務端提供的服務是可用的。可以使用管理工具查看確認。
C. spring 定時器的方法參數是否能動態修改
很多時候,spring的quartz定時任務並不能完全滿足項目的需要,經常會遇到需要任務的執行時間和頻率是可控的,而不是寫死在 quartz配置xml上面。為此,思考了很多動態修改任務執行的方法,以下方法是通過獲取scheler,對trigger的時間表達式進行修改,並重啟任務去實現任務的動態變化。
[java] view plain
public class QuartzHandler {
public static final String DEFAULT_GROUP_NAME = "DEFAULT";
private static QuartzHandler instance = new QuartzHandler();
private static Logger logger = Logger.getLogger(QuartzHandler.class);
private QuartzManager quartzManager;
private Scheler scheler;
private ApplicationContext context;
private QuartzHandler() {
}
public static QuartzHandler genInstance() {
return instance;
}
/**
* 開始定時任務
*/
public void start() {
context = new (
"spring/applicationContext.xml");
scheler = (StdScheler) context.getBean("schelerFactory");
quartzManager = (QuartzManager) context.getBean("quartzManager");
}
/**
* 更新定時任務的觸發表達式
*
* @param triggerName
* 觸發器名字
* @param groupName
* 觸發器組名字
* @param cronExpression
* 觸發表達式
* @return 成功則返回true,否則返回false
*/
public boolean updateCronExpression(String triggerName, String groupName,
String cronExpression) {
try {
CronTrigger trigger = (CronTrigger) getTrigger(triggerName,
groupName);
if (trigger == null) {
return false;
}
if (StringUtils.equals(trigger.getCronExpression(), cronExpression)) {
logger.info("cronExpression is same with the running Schele , no need to update.");
return true;
}
trigger.setCronExpression(cronExpression);
scheler.rescheleJob(trigger.getName(), trigger.getGroup(),
trigger);
logger.info("Update the cronExpression successfully!!");
return true;
} catch (ParseException e) {
logger.error("The new cronExpression - " + cronExpression
+ " not conform to the standard. " + e);
return false;
} catch (SchelerException e) {
logger.error("Fail to reschele. " + e);
return false;
}
}
/**
* 獲取觸發器
*
* @param triggerName
* 觸發器名字
* @param groupName
* 觸發器組名字
* @return 對應Trigger
*/
public Trigger getTrigger(String triggerName, String groupName) {
Trigger trigger = null;
if (StringUtils.isBlank(groupName)) {
logger.warn("Schele Job Group is empty!");
return null;
}
if (StringUtils.isBlank(triggerName)) {
logger.warn("Schele trigger Name is empty!");
return null;
}
try {
trigger = scheler.getTrigger(triggerName, groupName);
} catch (SchelerException e) {
logger.warn("Fail to get the trigger (triggerName: " + triggerName
+ ", groupName : " + groupName + ")");
return null;
}
if (trigger == null) {
logger.warn("Can not found the trigger of triggerName: "
+ triggerName + ", groupName : " + groupName);
}
return trigger;
}
}
D. java定時任務 spring配置了定時器 在執行run()時調用service 但是卻得不到hiberbate的連接
= =我也遇到這個問題,而且都不拋出異常。。。。!!!!!!!!!!!!!!我發現問題了,我用try catch列印異常發現是無法獲取session。我是因為aop切面出現問題,也就是事務有問題,因為我這個定時器沒有定義和實現介面,然後我配置的切面是在service包裡面,所以無法得到session。然後我增加了介面,放在service包裡面立馬沒問題了。果然還是事務配置有問題。雖然隔了很久了但是我還是要回復一下!!!!!!!!我現在心情很激動!!!我果然機智!!!!話說回來,spring我還是沒怎麼學好啊。
E. Spring 定時器 設置30秒 運行一次方法怎麼設置
//
import javax.swing.Timer;
import java.awt.*;
class A {
Timer timer;
//
public void A(){
ActionListener al=new ActionListener(){
public void actionPerformed(ActionEvent e){
hello();
}
};
timer =new Timer(30000,al);
timer.start();
}
public void hello(){
System.out.println("hello everyone");
}
}
F. spring定時器如何配置
有兩種流行Spring定時器配置:Java的Timer類和OpenSymphony的Quartz。
1.Java Timer定時
首先繼承java.util.TimerTask類實現run方法
import java.util.TimerTask;
public class EmailReportTask extends TimerTask{
@Override
public void run() {
...
}
}
在Spring定義
...
配置Spring定時器
<bean id="scheleReportTask" class="org.springframework.scheling.timer.ScheledTimerTask">
<property name="timerTask" ref="reportTimerTask" />
<property name="period">
<value>86400000value>
property>
bean>
timerTask屬性告訴ScheledTimerTask運行哪個。86400000代表24個小時
啟動Spring定時器
Spring的TimerFactoryBean負責啟動定時任務
<bean class="org.springframework.scheling.timer.TimerFactoryBean">
<property name="scheledTimerTasks">
<list><ref bean="scheleReportTask"/>list>
property>
bean>
scheledTimerTasks里顯示一個需要啟動的定時器任務的列表。
可以通過設置delay屬性延遲啟動
<bean id="scheleReportTask" class="org.springframework.scheling.timer.ScheledTimerTask">
<property name="timerTask" ref="reportTimerTask" />
<property name="period">
<value>86400000value>
property>
<property name="delay">
<value>3600000value>
property>
bean>
這個任務我們只能規定每隔24小時運行一次,無法精確到某時啟動
2.Quartz定時器
首先繼承QuartzJobBean類實現executeInternal方法
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheling.quartz.QuartzJobBean;
public class EmailReportJob extends QuartzJobBean{
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
...
}
}
在Spring中定義
<bean id="reportJob" class="org.springframework.scheling.quartz.JobDetailBean">
<property name="jobClass">
<value>EmailReportJobvalue>
property>
<property name="jobDataAsMap">
<map>
<entry key="courseService">
<ref bean="courseService"/>
entry>
map>
property>
bean>
在這里我們並沒有直接聲明一個EmailReportJob Bean,而是聲明了一個JobDetailBean。這個是Quartz的特點。JobDetailBean是Quartz的org.quartz.JobDetail的子類,它要求通過jobClass屬性來設置一個Job對象。
使用Quartz的JobDetail中的另一個特別之處是EmailReportJob的courseService屬性是間接設置的。JobDetail的jobDataAsMap屬性接受一個Map,包括設置給jobClass的各種屬性,當。JobDetailBean實例化時,它會將courseService Bean注入到EmailReportJob 的courseService 屬性中。
啟動定時器
Quartz的org.quartz.Trigger類描述了何時及以怎樣的頻度運行一個Quartz工作。Spring提供了兩個觸發器SimpleTriggerBean和CronTriggerBean。
SimpleTriggerBean與scheledTimerTasks類似。指定工作的執行頻度,模仿scheledTimerTasks配置 .
<bean id="simpleReportTrigger" class="org.springframework.scheling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="reprotJob" />
<property name="startDelay">
<value>360000value>
property>
<property name="repeatInterval">
<value>86400000value>
property>
bean>
startDelay也是延遲1個小時啟動
CronTriggerBean指定工作的准確運行時間
<bean id="cronReportTrigger" class="org.springframework.scheling.quartz.CronTriggerBean">
<property name="jobDetail" ref="reprotJob" />
<property name="cronExpression">
<value>0 0 6 * * ?value>
property>
bean>
屬性cronExpression告訴何時觸發。最神秘就是cron表達式:
Linux系統的計劃任務通常有cron來承擔。一個cron表達式有至少6個(也可能7個)有空格分隔的時間元素。從左到右:
1.秒2.分3.小時4.月份中的日期(1-31)5.月份(1-12或JAN-DEC)6.星期中的日期(1-7或SUN-SAT)7.年份(1970-2099)
每個元素都顯示的規定一個值(如6),一個區間(9-12),一個列表(9,11,13)或一個通配符(*)。因為4和6這兩個元素是互斥的,因此應該通過設置一個問號(?)來表明不想設置的那個欄位,「/」如果值組合就表示重復次數(10/6表示每10秒重復6次)。
啟動定時器
<bean class="org.springframework.scheling.quartz.SchelerFactoryBean">
<property name="triggers">
<list><ref bean="cronReportTrigger"/>list>
property>
bean>
triggers屬性接受一組觸發器。
G. 如何配置Spring定時器准確運行時間
Spring中有自帶任務調度框架Quartz ,直接在xml配置文件中配置就好。
H. java 定時器 怎麼跟spring結合
java定時器的使用( )
1、在應用開發中,經常需要一些周期性的操作,比如每5分鍾執行某一操作等。
對於這樣的操作最方便、高效的實現方式就是使用java.util.Timer工具類。
private java.util.Timer timer;
timer = new Timer(true);
timer.schele(
new java.util.TimerTask() { public void run()
{ //server.checkNewMail(); 要操作的方法} }, 0, 5*60*1000);
第一個參數是要操作的方法,第二個參數是要設定延遲的時間,第三個參
數是周期的設定,每隔多長時間執行該操作。
使用這幾行代碼之後,Timer本身會每隔5分鍾調用一遍
server.checkNewMail()方法,不需要自己啟動線程。Timer本身也是多線程同
步的,多個線程可以共用一個Timer,不需要外部的同步代碼。
2、
(1)Timer.schele(TimerTask task,Date time)安排在制定的時間執行指定的
任務。
(2)Timer.schele(TimerTask task,Date firstTime ,long period)安排指定
的任務在指定的時間開始進行重復的固定延遲執行.
(3)Timer.schele(TimerTask task,long delay)安排在指定延遲後執行指定的
任務.
(4)Timer.schele(TimerTask task,long delay,long period)安排指定的任務
從指定的延遲後開始進行重復的固定延遲執行.
(5)Timer.scheleAtFixedRate(TimerTask task,Date firstTime,long period)
安排指定的任務在指定的時間開始進行重復的固定速率執行.
(6)Timer.scheleAtFixedRate(TimerTask task,long delay,long period)安
排指定的任務在指定的延遲後開始進行重復的固定速率執行.
用Java Timer API 進行時間調度開發的相關注意點
java.util這個包中可以找到Timer和TimerTask這兩個類。Timer直接從Object
繼承,它相當於一個計時器,能夠用它來指定某個時間來執行一項任務,或者
每隔一定時間間隔反復執行同一個任務。創建一個Timer後,就會生成一個線程
在背後運行,來控制任務的執行。而TimerTask就是用來實現某項任務的類,
它實現了Runnable介面,因此相當於一個線程。
Timer 的構造方法 new Timer(true)如果參數為 true 的話,這個線程就是一個守護線程,導致我在後面調用幾個 timer.schele() 方法時,只有第一個被執行,後面幾個都被屏蔽了,如果把這個參數設置為 false ,後面的調用才能生效。
如何實現自己的任務調度?
1、繼承TimerTask,注意TimerTask是實現Runnable介面的,因此只要重載run()
方法即可。
2、創建Timer對象,調用schele()方法。
相關注意點分析:
1、任務調度要優先考慮實時保證
由於Java的天性,並且在開發JDK的過程中要考慮到不同平台,而不同平台的
線程調度機制是不同的,因此各種平台下JVM 的線程調度機制也是不一致的。
從而Timer不能保證任務在所指定的時間內執行。另外由於TimerTask是實現
Runnable介面的,在TimerTask被放進線程隊列睡眠一段時間(wait)之後,
當到了指定的該喚起該TimerTask時,由於執行的確切時機取決於JVM的調度策
略和當前還有多少線程在等待CPU處理。因此就不能保證任務在所指定的時間
內執行。通常在如下兩種情況下導致任務延遲執行:
(1)、有大量線程在等待執行
(2)、GC機制的影響導致延遲
這也是為什麼在Timer API中存在兩組調度方法的原因。即:
(1)、schele()
用固定延遲調度。使用本方法時,在任務執行中的每一個延遲會傳播到後續的任
務的執行。
(2)、scheleAsFixedRate()
用固定比率調度。使用本方法時,所有後續執行根據初始執行的時間進行調度,
從而希望減小延遲。
具體使用哪一個方法取決於哪些參數對你的程序或系統更重要。
2、每個Timer對象要在後台啟動一個線程。這種性質在一些託管的環境下不推
薦使用,比如在應用伺服器中。因為這些線程不在容器的控制范圍之內了。
具體Java API 中的Timer 類和TimerTask類的描述如下:
java.util
類Timer
java.lang.Object
java.util.Timer
public class Timer
extends Object
一種線程設施,用於安排以後在後台線程中執行的任務。可安排任務執行一次,
或者定期重復執行。
與每個Timer 對象相對應的是單個後台線程,用於順序地執行所有計時器任務。
計時器任務應該迅速完成。如果完成某個計時器任務的時間太長,那麼它會「獨
占」計時器的任務執行線程。因此,這就可能延遲後續任務的執行,而這些任務
就可能「堆在一起」,並且在上述令人討厭的任務最終完成時才能夠被快速連續
地執行。
對Timer 對象最後的引用完成後,並且所有未處理的任務都已執行完成後,計
時器的任務執行線程會正常終止(並且成為垃圾回收的對象)。但是這可能要很
長時間後才發生。默認情況下,任務執行線程並不作為守護線程來運行,所以
它能夠阻止應用程序終止。如果調用方想要快速終止計時器的任務執行線程,那
么調用方應該調用計時器的cancel 方法。
如果意外終止了計時器的任務執行線程,例如調用了它的stop 方法,那麼所有
以後對該計時器安排任務的嘗試都將導致IllegalStateException,就好像調用
了計時器的cancel 方法一樣。
此類是線程安全的:多個線程可以共享單個Timer 對象而無需進行外部同步。
此類不提供實時保證:它使用Object.wait(long) 方法來安排任務。
實現注意事項:此類可擴展到大量同時安排的任務(存在數千個都沒有問題)。
在內部,它使用二進制堆來表示其任務隊列,所以安排任務的開銷是O(log n),
其中n 是同時安排的任務數。
實現注意事項:所有構造方法都啟動計時器線程。
從以下版本開始:
1.3
另請參見:
TimerTask, Object.wait(long)
構造方法摘要
Timer()
創建一個新計時器。
Timer(boolean isDaemon)
創建一個新計時器,可以指定其相關的線程作為守護程序運行。
Timer(String name)
創建一個新計時器,其相關的線程具有指定的名稱。
Timer(String name, boolean isDaemon)
創建一個新計時器,其相關的線程具有指定的名稱,並且可以指定作為守護程序運
行。
方法摘要
void cancel()
終止此計時器,丟棄所有當前已安排的任務。
int purge()
從此計時器的任務隊列中移除所有已取消的任務。
void schele(TimerTask task, Date time)
安排在指定的時間執行指定的任務。
void schele(TimerTask task, Date firstTime, long period)
安排指定的任務在指定的時間開始進行重復的固定延遲執行。
void schele(TimerTask task, long delay)
安排在指定延遲後執行指定的任務。
void schele(TimerTask task, long delay, long period)
安排指定的任務從指定的延遲後開始進行重復的固定延遲執行。
void scheleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任務在指定的時間開始進行重復的固定速率執行。
void scheleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任務在指定的延遲後開始進行重復的固定速率執行。
從類java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
構造方法詳細信息
Timer
public Timer()
創建一個新計時器。相關的線程不作為守護程序運行。
另請參見:
Thread, cancel()
Timer
public Timer(boolean isDaemon)
創建一個新計時器,可以指定其相關的線程作為守護程序運行。如果計時器將用於
安排重復的「維護活動」,則調用守護線程,在應用程序運行期間必須調用守護線程,
但是該操作不應延長程序的生命周期。
參數:
isDaemon - 如果應該將相關的線程作為守護程序運行,則為true。
另請參見:
Thread, cancel()
Timer
public Timer(String name)
創建一個新計時器,其相關的線程具有指定的名稱。相關的線程不作為守護程序運
行。
參數:
name - 相關線程的名稱。
拋出:
NullPointerException - 如果name 為null。
從以下版本開始:
1.5
另請參見:
Thread.getName(), Thread.isDaemon()
Timer
public Timer(String name,
boolean isDaemon)
創建一個新計時器,其相關的線程具有指定的名稱,並且可以指定作為守護程序運
行。
參數:
name - 相關線程的名稱。
isDaemon - 如果應該將相關的線程作為守護程序運行,則為true。
拋出:
NullPointerException - 如果name 為null。