程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Jcrontab - java定時程序進階學習

Jcrontab - java定時程序進階學習

編輯:關於JAVA
 初學Jcrontab感覺非常好,用它來做一個定時程序非常容易,而且方便。有關Jcrontab的介紹和它的定時文件的格式,在前面的那篇文章已經介紹過了,這裡再來講解一下它在程序中的具體應用。在這裡,我們先約定數據源這個概念,“數據源”(我暫且這樣稱呼),它主要是用來由Jcrontab按照定時規則要處理的類和程序,這可以是多個,也可以是一個,我按照Jcrontab提供的方法通常是將它寫到文件中,XML文件或數據庫中。這樣,按照Jcrontab的規則,提供給Jcrontab這些數據源就可以使用Jcrotab的定時功能了。

根據Jcrontab存儲的不同的數據源,我們可以分成以下幾個:

  • 普通文件來存儲
  • 數據庫存儲
  • XML文件存儲

在程序中也可以添加要執行的數據源,比如執行本地的應用程序等。下面分別介紹一下。在這之前,先介紹一下有關Jcrontab用到的配置文件:

  • jcrontab.properties配置文件,這是用來啟動Jcrontab的必需文件。在Jcrontab的發布包中已經有一個完整格式的jcrontab.properties文件了,裡面有它的樣例,我們只需要根據我們自己的應用需要,來使用具體的配置屬性,來構造自己的jcrontab.propertIEs。
  • 還有一個配置文件就是我們自己的定時配置文件。(若我們采用的數據源是文件的話,就需要這個了)這個文件是用來寫負責處理定時程序的,裡面按照規定好的時間來處理規定好的類或類的方法。
  • 若我們采用數據庫存儲數據源的話,那麼,我們就需要配置一個數據庫的信息,在jcrontab.propertIEs文件中已經有一個例子了,我們可以改成我們需要的數據庫配置信息,這個很容易。
  • 若要采用的是XML形式的文件,那麼我們要指定數據源是XML的,同時指定處理XML的解析器,這裡用的是apache的Xerces。
  • 在程序中隨時可以添加數據源,通過Crontab中的newTask方法,就可以隨時添加。

通過文件記錄數據源
下面通過例子,我們來講解一個具體的Jcrontab程序,看它是如何定時處理程序的。 
運行程序的JCrontabApp類: JCrontabApp類 import org.jcrontab.Crontab;
import org.jcrontab.NativeExec;
import org.jcrontab.SendMail;
import org.jcrontab.data.CrontabParser;
import org.jcrontab.data.CrontabEntryBean;
import org.jcrontab.data.CrontabEntryDAO;
import Java.io.File;
public class JCrontabApp {
private static Crontab cron = null;
private String JcrontabFile = null;
public JCrontabApp() {
}
public String getJcrontabFile() {
return JcrontabFile;
}
public void setJcrontabFile(String jcrontabFile) {
JcrontabFile = jcrontabFile;
}
/**
* 初始化Jcrontab,通過指定的jcrontab.propertIEs來執行具體的操作
* 啟動Jcrontab
*/
protected void init() {
cron = Crontab.getInstance();
try {
ShutdownHook();
cron.setDaemon(false);
if (null == JcrontabFile)
cron.init();
cron.init(JcrontabFile);
System.out.println("Start Jcrontab...");
} catch (Java.lang.Exception e) {
e.printStackTrace();
}
}
/**
* 關閉Jcrontab的執行
* @throws Exception
*/
protected void ShutdownHook() throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Shutting down...");
cron.uninit(200);
System.out.println("Stoped Jcrontab!");
}
});
}
/**
* 判斷是否是Holiday
* @return
* @throws Exception
*/
public boolean isHoliday()throws Exception{
return cron.isHoliday();
}
/**
* 根據不同的參數執行不同的定時程序,可選參數可從main方法中查看
* @param args
* @throws Exception
*/
public void exectue(String[] args) throws Exception {
if (args.length < 2) {
return;
}
this.setJcrontabFile(args[0]);
init();
if ("database".equals(args[1]))
executeDatabase();
else if ("appliction".equals(args[1])) {
String[] parameters = new String[args.length-2];
System.arraycopy(args,2,parameters,0,args.length-2);
cron.newTask("org.jcrontab.NativeExec","main",parameters);
} else if ("Javamail".equals(args[1]))
executeJavaMail(args[2]);
}
/**
* 執行數據庫的操作
* @throws Exception
*/
protected void executeDatabase() throws Exception {
CrontabParser cp = new CrontabParser();
CrontabEntryBean[] ceb = new CrontabEntryBean[2];
ceb[0] = cp.marshall("* * * * * com.aweb.test.NumTest 123");
ceb[0].setYears("*");
ceb[0].setSeconds("0");
ceb[0].setBusinessDays(true);
ceb[0].setId(0);
ceb[1] = cp.marshall("* * * * * com.aweb.test.LetterTest 234");
ceb[1].setYears("*");
ceb[1].setSeconds("0");
ceb[1].setBusinessDays(true);
ceb[1].setId(1);
CrontabEntryDAO.getInstance().store(ceb);
}
/**
* 執行本地的應用程序的操作
* @param parameters
*/
protected void executeAppliction(String[] parameters) {
NativeExec.main(parameters);
}
/**
* 將執行的文件發送為email
* @param sendFilename
* @throws Exception
*/
protected void executeJavaMail(String sendFilename) throws Exception {
File sendFile = new File(sendFilename);
SendMail sm = new SendMail();
sm.send(sendFile);
}
/**
* 主要通過main方法來實現Jcrontab的實現
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception {
if (args.length < 2) {
System.out.println("Usage:The values of args:<-type>[]");
System.out.println("********************************************************");
System.out.println("Optional Parameters of type:");
System.out.println("-filedata:doing file Operating.");
System.out.println("-database:doing database Operating.");
System.out.println("-appliction :doing native application execute.");
System.out.println("-Javamail :doing Javamail Operating.");
System.out.println("********************************************************");
System.exit(1);
}
JCrontabApp jp = new JCrontabApp();
jp.exectue(args);
System.out.println(jp.isHoliday());
}
}

帶測試運行的NumTest類和LetterTest類:

NumTest類 public class NumTest {
public static void main(String args[]){
for(int i=0;i<10;i++){
System.out.println("Time:"+System.currentTimeMillis()+" i= "+i);
}

}
LetterTest類
 public class LetterTest {
public static void main(String args[]) {
System.out.println("Time: " + System.currentTimeMillis() + " Letter: " + "hello World!");
}
}


配置文件Jcrontab.propertIEs:

Jcrontab.propertIEs文件 ##
#Mon May 24 19:12:24 CEST 2004
org.jcrontab.version=2.0.RC1
org.jcrontab.log.Logger=org.jcrontab.log.Log4JLogger
org.jcrontab.log.log4J.Properties=log4j.propertIEs
org.jcrontab.data.file = crontab
org.jcrontab.data.datasource = org.jcrontab.data.FileSource
org.jcrontab.Crontab.refreshFrequency = 3

處理定時程序的crontab文件:

crontab文件 * * * * * com.aweb.test.NumTest
* * * * * com.aweb.test.LetterTest


然後,我們在命令行輸入jcrontab.propertIEs文件的位置,和要處理的類型,這裡,我們選filedata,接著運行該類,我們就可以看到它的執行結果:

[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.log.log4J.Properties : log4j.propertIEs
[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.version : 2.0.RC1
[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.Crontab.refreshFrequency : 3
[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.data.file : crontab.propertIEs
[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.data.datasource : org.jcrontab.data.FileSource
[2004-10-19 16:10:20,296 LV:DEBUG CL:jcrontab] org.jcrontab.log.Logger : org.jcrontab.log.Log4JLogger
Start Jcrontab...

[2004-10-19 16:10:20,500 LV:DEBUG CL:jcrontab] Interval to sleep : 39984
[2004-10-19 16:11:00,484 LV: INFO CL:jcrontab] com.aweb.test.NumTest# 
[2004-10-19 16:11:00,484 LV: INFO CL:jcrontab] com.aweb.test.LetterTest# 
[2004-10-19 16:11:00,484 LV:DEBUG CL:jcrontab] Interval to sleep : 60000
Time:1098173460484 i= 0
Time:1098173460484 i= 1
Time:1098173460484 i= 2
Time:1098173460484 i= 3
Time:1098173460484 i= 4
Time:1098173460484 i= 5
Time:1098173460484 i= 6
Time:1098173460500 i= 7
Time:1098173460500 i= 8
Time:1098173460500 i= 9
Time: 1098173460515 Letter: hello World!

這樣每隔一分鐘,就會運行一次NumTest類和LetterTest類 

  1. 通過數據庫記錄數據源
    在進行數據庫的操作前,你需要在數據庫中建一張表,這個表在Jcrontab中有它的SQL語句,events表,它的表結構,可以參考Jcrontab提供的SQL語句。我們只需要將crontab文件中的屬性做一下修改就可以了
    修改後的crontab文件: crontab文件

    增加下面的屬性:

    org.jcrontab.data.GenericSQLSource.driver = org.gjt.mm.MySQL.Driver
    org.jcrontab.data.GenericSQLSource.url = jdbc:MySQL://127.0.0.1/netbook
    org.jcrontab.data.GenericSQLSource.username = root
    org.jcrontab.data.GenericSQLSource.passWord = 
    org.jcrontab.data.datasource = org.jcrontab.data.GenericSQLSource
    這樣,我們再在命令行下輸入jcrontab.propertIEs文件的位置,和要處理的類型,這裡,我們選database,就可以執行我們寫好的兩個類了。運行時,它是先將這兩個待處理的類的數據源,按照規定好的數據庫中的字段,一一存入數據庫中,然後再從數據庫中讀取events表中的每一行(這每一行就是待處理的數據源),它就根據這些行定時處理。執行的結果同上。
  2. 通過XML來存儲數據源
    其實和文件存儲差不多,主要這裡要用到XML的解析器,這裡用的是apache Xerces來處理的,其它的都一樣。
    修改後的crontab文件: crontab文件

    去掉原來的crontab文件中的信息,加上下面的屬性

    org.jcrontab.data.file = crontab.XML
    org.XML.sax.driver=org.apache.xerces.parsers.SAXParser
    org.jcrontab.data.datasource=org.jcrontab.data.XMLSource
    同樣在命令行下輸入jcrontab.propertIEs文件的位置,和要處理的類型,這裡和文件的一樣選filedata,來運行該類,執行結果同上。
  3. 定時處理程序,還可以用來處理本地的應用程序
    根據系統的不同,可以處理不同的應用程序,比如:執行ping的命令,那麼你就可以調用Jcrontab中已經寫好的NativeExec類來執行即可。它主要負責處理本地系統上的應用程序。我們在XML文件中添加一條記錄,就可以實現了。
    修改後的crontab文件: crontab.XML文件 <?XML version="1.0" encoding="GB2312"?>

    <CRONTAB>

    <SECONDS>0</SECONDS>
    <MINUTES>*</MINUTES>
    <HOURS>*</HOURS>
    <DAYSOFMONTH>*</DAYSOFMONTH>
    <MONTHS>*</MONTHS>
    <DAYSOFWEEK>*</DAYSOFWEEK>
    <YEARS>*</YEARS>
    <BUSSINESDAYS>true</BUSSINESDAYS>
    <STARTDATE>null</STARTDATE>
    <ENDDATE>null</ENDDATE>
    <CLASS>com.aweb.test.NumTest</CLASS>
    <method>main</method>
    <DESCRIPTION>null</DESCRIPTION>
    </CRONTABENTRY>
    <CRONTABENTRY id=1>
    <SECONDS>0</SECONDS>
    <MINUTES>*</MINUTES>
    <HOURS>*</HOURS>
    <DAYSOFMONTH>*</DAYSOFMONTH>
    <MONTHS>*</MONTHS>
    <DAYSOFWEEK>*</DAYSOFWEEK>
    <YEARS>*</YEARS>
    <BUSSINESDAYS>true</BUSSINESDAYS>
    <STARTDATE>null</STARTDATE>
    <ENDDATE>null</ENDDATE>
    <CLASS>com.aweb.test.LetterTest</CLASS>
    <method>main</method>
    <DESCRIPTION>null</DESCRIPTION>
    </CRONTABENTRY>
    <CRONTABENTRY id=2>
    <SECONDS>0</SECONDS>
    <MINUTES>*</MINUTES>
    <HOURS>*</HOURS>
    <DAYSOFMONTH>*</DAYSOFMONTH>
    <MONTHS>*</MONTHS>
    <DAYSOFWEEK>*</DAYSOFWEEK>
    <YEARS>*</YEARS>
    <BUSSINESDAYS>true</BUSSINESDAYS>
    <STARTDATE>null</STARTDATE>
    <ENDDATE>null</ENDDATE>
    <CLASS>org.jcrontab.NativeExec</CLASS>
    <method>main</method>
    <PARAMETERS>net send 192.168.0.109 "你好!每一分鐘出現一次!呵呵"</PARAMETERS>
    <DESCRIPTION>null</DESCRIPTION>
    </CRONTABENTRY>
    </CRONTAB>
    這樣執行的結果就是每隔一分鐘就會執行一次net send命令(是不是裝了個定時炸彈呀!呵呵,不過是在服務器端才運行的喲!)。
  4. 通過Email來發送執行的數據源
    在Jcrontab中提供了JavaMail的功能,你可以用JavaMail來實現上面同樣的功能。你只需要修改一下配置文件
    修改後的crontab文件: crontab文件

    增加下面的屬性

    <A href="mailto:[email protected]">[email protected]</A>
    <A href="mailto:[email protected]">[email protected]</A>
    org.jcrontab.SendMail.smtp.host=smtp.sohu.com
    org.jcrontab.SendMail.smtp.username= yourname
    org.jcrontab.SendMail.smtp.password=passWord
    這樣它就會將執行的數據源發送到你的郵箱中。不過,目前這個我沒有測試成功,我認為主要是由於郵件服務器的原因吧,它總是出現JavaMail的運行異常。程序方面應該不會有問題,這需要我在以後的學習中繼續來完成,也希望大家幫我實現這個功能!

總結:Jcrontab提供的定時處理程序的功能不單單是這些,還可以定時處理EJB等高級的組件,在應用服務器中也可以采用Servlet的方式來定時處理(個人感覺:它提供的用Servlet來定時處理程序的功能不太好!大家去慢慢體會吧!)。還有一些其它方面的功能,還需要繼續的學習和探索!

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved