對天乙社區bbscs8實現的詳細分析十一

此文爲轉載:http://www.diybl.com/course/1_web/webjs/2007113/82989.html



到這裏爲此,我們已經將主要的業務邏輯給理解完成了,也將bean包、service包和service.imp及service.web,以及dao層和fio層包大部分內容都講了一遍.現在我們將service層包中還剩下的幾個主要包(scheduling和task)給講一遍,首先我們還是從com.laoer.bbscs.service.mail包的TemplateMail開始,這是一個發mail的服務類文件,引入了tempConfiguartaion和sysConfig,並且使用了Jakarta發佈了Commons Emails版HtmlEmail,使用時,先用init()初始化,再使用之:
public void init() throws Exception {
if (this.getSysConfig().getSmtpAuth() == 1) {//是否服務器需授權
   DefaultAuthenticator defaultAuthenticator = new DefaultAuthenticator(
     this.getSysConfig().getSmtpUser(), this.getSysConfig()
       .getSmtpPasswd());//加入帳號密碼
   this.getHtmlEmail().setAuthenticator(defaultAuthenticator);
}

this.getHtmlEmail().setHostName(this.getSysConfig().getSmtpServer());
this.getHtmlEmail().setSmtpPort(this.getSysConfig().getSmtpPort());
this.getHtmlEmail().setFrom(this.getSysConfig().getSenderEmail());
this.getHtmlEmail().setTextMsg(
    "Your email client does not support HTML messages");
this.getHtmlEmail().setCharset(Constant.CHARSET);//stmp服務器配置

this.getTempConfiguration().setDirectoryForTemplateLoading(new File(Constant.ROOTPATH + Constant.FTL_PATH));
this.getTempConfiguration().setDefaultEncoding(Constant.CHARSET);
this.getTempConfiguration().setNumberFormat("0.##########");//freemarker模板初始化
}
使用時,用sendMainFromTemplate,附加一些參數,便能發送基於Html的郵件了!其中的ftlName可是補填充的mailSend.ftl或mailSendTopic.ftl(見WEB-INF/templates/..),這裏需要知道的是java.io.StringWriter類extends Writer ,它將輸出收集到一個字符緩存區中的一個字符流,用於構造一個串.(具體指的是將板裏包含的所有內容(格式化後)輸出成流形式吧)
/**
flush()
清空流。
getBuffer()
返回串緩存區。
toString()
返回作爲一個串的緩存區的當前值
*/
public void sendMailFromTemplate(String to, String subject, String ftlName,
   Map root, Locale locale) {
this.getTempConfiguration().setLocale(locale);
try {
   this.getHtmlEmail().setSubject(subject);
   Template temp = this.getTempConfiguration().getTemplate(ftlName);
   StringWriter sw = new StringWriter();
   temp.process(root, sw);//ftl文件--->sw流,可見FreeMarker和Spring的API
   this.getHtmlEmail().setHtmlMsg(sw.toString());
   this.getHtmlEmail().addTo(to);
   this.getHtmlEmail().send();
   sw.flush();
} catch (Exception e) {
   logger.error(e);
}
}
接下來,我將分析spring中的計劃任務和調度,資料請查考:
http://book.csdn.net/bookfiles/167/1001677368.shtml<spring in action>
第一步是從java.util.TimerTask中派生,run()方法定義了當任務運行時該做什麼。調度定時器任務:Spring的ScheduledTimerTask定義了一個定時器任務的運行週期。屬性timerTask告訴ScheduledTimerTask運行哪個TimerTask。屬性period告訴ScheduledTimerTask以怎樣的頻度調用TimerTask的run()方法。這個屬性以毫秒作爲單位.最後一步是啓動定時器。Spring的TimerFactoryBean負責啓動定時任務。按以下方式在Spring配置文件中聲明它,屬性scheduledTimerTasks要求一個需要啓動的定時器任務的列表,即使使用deplay屬性,Task的第一次運行時間仍然是相對於應用程序的啓動時間的。爲了能夠精確指定何時發送電子郵件,你需要使用Quartz調度器.
定義Quartz工作的第一步是創建一個類來定義工作。要做到這一點,你需要從Spring的QuartzJobBean中派生子類,QuartzJobBean是Quartz中與Java的TimerTask等價的類。它實現了org.quartz.Job接口。executeInternal()方法定義了當預定的時刻來臨時應該執行哪些動作。JobDetailBean是applicationContext.xml中定義,jobClass和jobDataAsMap,Quartz的org.quartz.Trigger類描述了何時及以怎樣的頻度運行一個Quartz工作。CronTriggerBean允許你更精確地控制任務的運行時間(其中屬性cronExpression告訴觸發器何時觸發).Spring的SchedulerFactoryBean是Quartz中與TimerFactoryBean等價的類,屬性triggers接受一組觸發器。OK!
我們的系統要兩種調度方式是由於其中之一是對時間的精確度決定的,首先看BoardCountTimerTask,應該是對版區帖子數的計算吧:作爲一個服務,先引入logger!它繼承了TimerTask,並且注入了BoardService和CommendSerivce兩個,可見applicationContext:
<bean id="boardCount"
class="com.laoer.bbscs.service.task.BoardCountTimerTask">
<property name="boardService">
   <ref local="boardService" />
</property>
<property name="commendService">
   <ref local="commendService" />
</property>
</bean>
看它的run()方法:
public void run() {
    try {
      logger.info("Board count start...");
      this.getBoardService().saveBoardsPostNumCount();//所有版區的帖子(包括主帖和帖子數統計,帖子有歷史帖和forum帖)
      this.getCommendService().createCommendTopFile(10);//前十的推薦帖寫入文件 hql:from Commend where commendTop = ? order by createTime desc commendTop是否推薦到首頁0爲是,注意寫入到文件時的方法參數0指的文件名字符,沒其它作用 include/Commend_0.html
      logger.info("Board count end");
    }
    catch (BbscsException ex) {
      logger.error(ex);
    }
}
好了,看下spring中怎麼用這個Task:(調度配置)
<bean id="boardCountTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
   <value>10000</value>//10秒
</property>
<property name="period">
   <value>1800000</value>//30分鐘一次
</property>
<property name="timerTask">
   <ref local="boardCount" />//用的是誰?
</property>
</bean>
對於啓動,則由timerFactory寄居:
<bean id="timerFactory"
class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
   <list>
    <ref local="loginErrorClearTimerTask" />//包括所有的TimerTask事件!
    <ref local="voteUserClearTimerTask" />
    <ref local="forumHistoryTimerTask" />
    <ref local="userOnlineClearTimerTask" />
    <ref local="boardCountTimerTask" />
    <ref local="subscibeSendTimerTask" />
   </list>
</property>
</bean>

接下來,我們看ForumHistoryTimerTask:
public void run() {
long htime = (long) (this.getSysConfig().getPostToHistoryDay()) * 24l * 3600000l;//用於了SysConfig配置服務,htime是個間隔時間,注意l爲long!
/**
public int getPostToHistoryDay() {
return this.getIntValue("PostToHistoryDay", 90);
}
*/
long atime = System.currentTimeMillis() - htime;//90天前的long型時間值
try {
   logger.info("ForumHistory Move Start...");
   logger.info("htime:" + htime + " atime:" + atime);
   this.getForumService().removeToHistory(atime);移動到forumHistory表
   logger.info("ForumHistory Move End");
} catch (BbscsException ex) {
   logger.error(ex);
}
}
/**
public void removeToHistory(long atime) throws BbscsException {
List ml = this.getForumDAO().findForumsToHistory(atime);//見下
for (int i = 0; i < ml.size(); i++) {
   Forum f = (Forum) ml.get(i);
   List fl = this.getForumDAO().findForumsTopic(f.getBoardID(), f.getId(), 0, 0, -1, null);//找到以這個帖子爲mainId版區內的所有回覆帖,它們跟隨一起進入歷史!
   for (int j = 0; j < fl.size(); j++) {
    Forum mf = (Forum) fl.get(j);
    Forum fh = new ForumHistory();
    try {
     BeanUtils.copyProperties(fh, mf);//拷貝bean屬性
     this.getForumHistoryDAO().saveForum(fh);//加入歷史
     this.getForumDAO().removeForum(mf);//從froum中去之
    } catch (Exception ex) {
     logger.error(ex);
     throw new BbscsException(ex);
    }
   }
}
}

public List findForumsTopic(final long bid, final String mainID, final int delSign, final int auditing,
   final int auditingAttachFile, final OrderObj[] oo) {
return getHibernateTemplate().executeFind(new HibernateCallback() {
   public Object doInHibernate(Session s) throws HibernateException {
    Criteria c = s.createCriteria(getForumClass());
    c.add(Restrictions.eq("mainID", mainID));
    c.add(Restrictions.eq("boardID", new Long(bid)));
    if (delSign != -1) {
     c.add(Restrictions.eq("delSign", new Integer(delSign)));
    }
    if (auditing != -1) {
     c.add(Restrictions.eq("auditing", new Integer(auditing)));
    }
    if (auditingAttachFile != -1) {
     c.add(Restrictions.eq("auditingAttachFile", new Integer(auditingAttachFile)));
    }

    if (oo != null && oo.length > 0) {
     for (int i = 0; i < oo.length; i++) {
      if (StringUtils.isNotBlank(oo[i].getOrderBy())) {
       if (oo[i].getAscOrDesc() == Constant.ORDER_ASC) {
        c.addOrder(Order.asc(oo[i].getOrderBy()));
       }
       if (oo[i].getAscOrDesc() == Constant.ORDER_DESC) {
        c.addOrder(Order.desc(oo[i].getOrderBy()));
       }
      }
     }
    }
    return c.list();
   }
});
}
public List findForumsToHistory(long atime) {
String sql = "from ForumMain where isNew = 1 and elite = 0 and lastTime <= ?";
return this.getHibernateTemplate().find(sql, new Long(atime));
}
*/
我們看它的配置:
<bean id="forumHistoryTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
   <property name="delay">
   <value>43200000</value>
</property>
<property name="period">
   <value>43200000</value> //12個小時!
</property>
<property name="timerTask">
   <ref local="forumHistoryTimer" />
</property>
</bean>
<bean id="forumHistoryTimer"
class="com.laoer.bbscs.service.task.ForumHistoryTimerTask">
<property name="forumService">
   <ref local="forumService" />//需注意它加入了事務處理功能!!!
</property>
<property name="sysConfig">
   <ref bean="sysConfig" />
</property>
</bean>

下面看LoginErrorClearTimerTask:
public void run() {
    long atime = System.currentTimeMillis() - (15 * 6000);//比現在晚15*6000/1000=90秒以上的錯誤!
    try {
      logger.info("Start LoginErrorClearTimerTask...");
      this.getLoginErrorService().removeLoginErrorsOutTime(atime);//簡單方法哦!
      logger.info("End LoginErrorClearTimerTask");
    }
    catch (BbscsException ex) {
      logger.error(ex);
    }
}
它在spring中的配置:
<bean id="loginErrorClearTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
   <value>15000</value>//15秒
</property>
<property name="period">
   <value>900000</value>//15分鐘
</property>
<property name="timerTask">
   <ref local="loginErrorClear" />
</property>
</bean>

看SubscibeSendTimerTask在applicationContext中的bean配置:
<bean id="subscibeSend"
class="com.laoer.bbscs.service.task.SubscibeSendTimerTask">
<property name="subscibeService">
   <ref local="subscibeService" />
</property>
<property name="subscibeQueue">
   <ref local="subscibeQueue" />
</property>
<property name="noteFactory">
   <ref local="noteFactory" />
</property>
<property name="noteService">
   <ref bean="noteService" />
</property>
<property name="messageSource">
   <ref bean="messageSource" />
</property>
<property name="templateMail">
   <ref bean="templateMail" />
</property>
<property name="sysConfig">
   <ref bean="sysConfig" />
</property>
<property name="boardService">
   <ref bean="boardService" />
</property>
<property name="forumService">
   <ref local="forumService" />
</property>
</bean>
--><bean id="boardService" parent="txProxyTemplate">
<property name="target">
   <ref bean="boardTarget" />
</property>
</bean>
<bean id="noteFactory"
class="com.laoer.bbscs.service.imp.NoteFactoryImp">
</bean>
<bean id="templateMail"
class="com.laoer.bbscs.service.mail.TemplateMail" scope="prototype"
init-method="init">
<property name="sysConfig">
   <ref bean="sysConfig" />
</property>
</bean>
public void run() {
logger.info("Send Subscibe, subscibeQueue's Num:" + this.getSubscibeQueue().size());
/**
subscibeQueue其實是com.laoer.bbscs.comm.SysQueue,它是一個隊列類,由Vector同步存取東西,大多方法都是syncharonized:
public synchronized void add(Object o) {
aVector.add(o);
}
public synchronized Object get() {
if (isEmpty()) {
   return null;
}
Object o = aVector.elementAt(0);
aVector.removeElementAt(0);
return o;
}
*/
while (this.getSubscibeQueue().size() > 0) {//隊列中有subscibe才執行!
   Forum f = (Forum) this.getSubscibeQueue().get();
/**
public synchronized Object get() {
if (isEmpty()) {
   return null;
}
Object o = aVector.elementAt(0);//隊頭取,並且減一
aVector.removeElementAt(0);
return o;
}
*/
   if (f != null) {//有數據
    List sendlist = this.getSubscibeService().findSubscibesSend(f.getMainID(), f.getBoardID());//最後查詢的HQL"from Subscibe where postID = ?";//找到訂閱了post爲f的主帖的所有subscibe(因爲有許多人訂)
    Date sdate = new Date();
    for (int i = 0; i < sendlist.size(); i++) {
     Subscibe subs = (Subscibe) sendlist.get(i);
     if (!subs.getUserID().equals(f.getUserID())) {//不是自己啊!
      if (subs.getMsginform() == 1) {//短信方式
       Note inboxNote = this.getNoteFactory().getInstance(subs.getUserID());//由userID產生一個Note對象
       inboxNote.setCreateTime(sdate);
       inboxNote.setFromID(f.getUserID());
       inboxNote.setFromNickName(f.getNickName());
       inboxNote.setFromUserName(f.getUserName());
       inboxNote.setIsNew(1);
       inboxNote.setIsRe(0);
       inboxNote.setNeedRe(0);
       String t = "<a href=""
         + BBSCSUtil.getActionMappingURLWithoutPrefix("read?action=topic&bid="
           + f.getBoardID() + "&id=" + f.getMainID()) + "">" + f.getTitle() + "</a>";
       inboxNote.setNoteContext(this.getMessageSource().getMessage("subs.content",
         new String[] { t }, BBSCSUtil.getLocale(subs.getUserLocale())));
       inboxNote.setNoteTitle(this.getMessageSource().getMessage("subs.title",
         new String[] { BBSCSUtil.getSpeShortString(f.getTitle(), 40, "...") },
         BBSCSUtil.getLocale(subs.getUserLocale())));
       inboxNote.setNoteType(1);
       inboxNote.setToID(subs.getUserID());//to是訂閱者
       inboxNote.setToNickName(subs.getNickName());
       inboxNote.setToUserName(subs.getUserName());
       inboxNote.setSysMsg(1);//系統消息
       try {
        this.getNoteService().saveNote(inboxNote);
       } catch (BbscsException ex) {
        logger.error(ex);
       }
      }
      if (subs.getEmailinform() == 1) {
       if (StringUtils.isNotBlank(subs.getUserEmail()) && this.getSysConfig().getUseEmail() == 1) {//可以發信並且用戶信箱不爲空
        Board board = this.getBoardService().getBoardByID(f.getBoardID());
        if (board != null) {//有這個帖子所在的論壇
         try {

          String detail = this.getForumService().getForumDetail(f, false);
          if (f.getEditType() == 0) {
           detail = BBSCSUtil.filterText(detail, (board.getAllowHTML() == 1),
             (board.getAllowUBB() == 1), true);

          }
Stringsubject = f.getTitle();
          Map<String, String> root = new HashMap<String, String>();
          root.put("website", this.getSysConfig().getWebName());//sysConfig服務
          root.put("title", f.getTitle());
          root.put("detail", detail);
          root.put("url", "");
          this.getTemplateMail().sendMailFromTemplate(subs.getUserEmail(), subject,
            "mailSend.ftl", root, BBSCSUtil.getLocale(subs.getUserLocale()));//調用TemplateMail完成發信

         } catch (Exception ex7) {
          ex7.printStackTrace();
          logger.error(ex7);
         }
        }
       }
      }
     }
    }
   }
}
logger.info("Send Subscibe End");

}
這裏注入了MessageSource,注意它有三個參數:code,arg,locale.讓我們進入它的內容BaseAction.properties:
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
   <list>
    <value>com.laoer.bbscs.web.action.BaseAction</value>
   </list>
</property>
</bean>
我們查找subs.content和subs.title兩項內容:
subs.title=訂閱主題通知:《{0}》
subs.content=您訂閱的帖子有人回覆了,標題《{0}》
new String[] { t }爲content的arg,其中String t = "<a href=""
         + BBSCSUtil.getActionMappingURLWithoutPrefix("read?action=topic&bid="
           + f.getBoardID() + "&id=" + f.getMainID()) + "">" + f.getTitle() + "</a>";
好了,讓我們看看subscibe的時間配置:
<bean id="subscibeSendTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
   <value>300000</value>//5分鐘
</property>
<property name="period">
   <value>300000</value>//5分鐘
</property>
<property name="timerTask">
   <ref local="subscibeSend" />
</property>
</bean>


Go on!UserOnlineTimerTask:
public void run() {
    long atime = System.currentTimeMillis() - 3600000;//1個小時清理一次
    try {
      logger.info("UserOnline Clear...");
      this.getUserOnlineService().removeUserOnlineOutTime(atime);//最終的HQL:private static final String REMOVE_ALL_OUTTIME = "delete from UserOnline where onlineTime < ?";
      logger.info("UserOnline Clear End");
    }
    catch (BbscsException ex) {
      logger.error(ex);
    }
}
<bean id="userOnlineClearTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
   <value>3600000</value>//1個小時
</property>
<property name="period">
   <value>3600000</value>
</property>
<property name="timerTask">
   <ref local="userOnlineClear" />
</property>
</bean>

還有一個VoteUserClearTimerTask:
public void run() {
    long atime = System.currentTimeMillis() - (24 * 3600000);//24小時
    try {
      logger.info("Vote user clear...");
      this.getAgreeAgainstService().removeOutTime(atime);//去掉過時的對帖子支持反對記錄,最終HQL: private static final String REMOVE_OUTTIEM = "delete from AgreeAgainst where createTime < ?";//一天不一樣!
      this.getVoteUserService().removeOutTime(atime);
      logger.info("Vote user clear end");
    }
    catch (BbscsException ex) {
      logger.error(ex);
    }
}
<bean id="voteUserClearTimerTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay">
   <value>45000</value> //45秒
</property>
<property name="period">
   <value>86400000</value>//24小時
</property>
<property name="timerTask">
   <ref local="voteUserClear" />
</property>
</bean>

好了,我們對scheduling包中的內容進行分析:
ForumArchivesJob首先繼承了QuartzJobBean,而executeInternal()是它的重要方法:
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
try {
   logger.info("###存檔###");
   this.getForumArchivesService().createForumArchives();//見本文開頭的講述!
   logger.info("###存檔結束###");
} catch (BbscsException e) {
   logger.error(e);
}
我們主要看它在spring的配置文件中的定義:
<bean name="forumArchivesJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
   <value>
    com.laoer.bbscs.service.scheduling.ForumArchivesJob
   </value>
</property>
<property name="jobDataAsMap">
   <map>
    <entry key="forumArchivesService">
     <ref local="forumArchivesService" />
    </entry>
   </map>
</property>
</bean>
}
其時間定製器:
<bean id="forumArchivesJobCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
   <ref bean="forumArchivesJob" />
</property>
<property name="cronExpression">
   <value>0 30 4 1 * ?</value> 每個月一號早上4:30運行
</property>
</bean>
而啓動者:
<bean
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
   <list>
    <ref local="sysNumStatJobCronTrigger" />
    <ref local="userTopFileJobCronTrigger" />
    <ref local="forumArchivesJobCronTrigger" />
   </list>
</property>
</bean>

看下一個:SysNumStatJob
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
java.util.Calendar cld = java.util.Calendar.getInstance();
cld.setTime(new Date());
cld.add(java.util.Calendar.DATE, -1);//5.19(統計前一天)
logger.info(Util.formatDate(cld.getTime()) + " 統計數據");

SysNumStat snsnow = new SysNumStat();//生成一個bean
snsnow.setCreateTime(System.currentTimeMillis());
long usernumall = this.getUserService().getAllUserNum();
logger.info("社區人數:" + usernumall);
long postNum = this.getForumService().getForumNum(-1) + this.getForumHistoryService().getForumNum(-1);
/**
public long getForumDelNum(long bid) {
return this.getForumDAO().getForumNum(bid, -1, 1, -1, -1);
}bid=-1爲所有版區
*/
long postMainNum = this.getForumService().getForumMainNum(-1)
    + this.getForumHistoryService().getForumMainNum(-1);
logger.info("主題數:" + postMainNum);//今天數
logger.info("帖子總數:" + postNum);
snsnow.setNum0(usernumall);
snsnow.setNum1(postMainNum);
snsnow.setNum2(postNum);
snsnow.setNum3(0);
snsnow.setNum4(0);
snsnow.setNum5(0);

cld.add(java.util.Calendar.DATE, -1);//5.18
logger.info("查找 " + Util.formatDate(cld.getTime()) + " 數據");
SysNumStat sns = this.getSysNumStatService().findSysNumStatByRecDate(Util.formatDate4(cld.getTime()));//最終得到private static final String LOAD_BY_RECDATE = "from SysNumStat where recDate = ?";

if (sns == null) {
   snsnow.setNumInc0(0);
   snsnow.setNumInc1(0);
   snsnow.setNumInc2(0);
   snsnow.setNumInc3(0);
   snsnow.setNumInc4(0);
   snsnow.setNumInc5(0);
} else {
   snsnow.setNumInc0(usernumall - sns.getNum0());//昨天增加數,見下:
/**
`Num0` int(11) default ?', //註冊人數
`NumInc0` int(11) NOT NULL default ?', //註冊人數增加數
`Num1` int(11) NOT NULL default ?', //主題數
`NumInc1` int(11) NOT NULL default ?', //主題增加數
`Num2` int(11) NOT NULL default ?', //帖子總數
`NumInc2` int(11) NOT NULL default ?', //帖子總數增加數
*/
   snsnow.setNumInc1(postMainNum - sns.getNum1());
   snsnow.setNumInc2(postNum - sns.getNum2());
   snsnow.setNumInc3(0);
   snsnow.setNumInc4(0);
   snsnow.setNumInc5(0);
}

cld.add(java.util.Calendar.DATE, 1);//5.19
logger.info("記錄 " + Util.formatDate(cld.getTime()) + " 數據");
try {
   this.getSysNumStatService().saveSysNumStat(Util.formatDate4(cld.getTime()), snsnow);//5.19
} catch (BbscsException ex) {
   logger.error(ex);
}
}
好,我們看它的配置:
<bean name="sysNumStatJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
   <value>
    com.laoer.bbscs.service.scheduling.SysNumStatJob
   </value>
</property>
<property name="jobDataAsMap">
   <map>
    <entry key="sysNumStatService">
     <ref local="sysNumStatService" />
    </entry>
    <entry key="userService">
     <ref local="userService" />
    </entry>
    <entry key="forumService">
     <ref local="forumService" />
    </entry>
    <entry key="forumHistoryService">
     <ref local="forumHistoryService" />
    </entry>
   </map>
</property>
</bean>
<bean id="sysNumStatJobCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
   <ref bean="sysNumStatJob" />
</property>
<property name="cronExpression">
   <value>0 0 1 * * ?</value>//每天早上1點的時候運行
</property>
</bean>
我們這裏可以參考下面的資料:
cronExpression配置說明
字段   允許值   允許的特殊字符
秒    0-59    , - * /
分    0-59    , - * /
小時    0-23    , - * /
日期    1-31    , - * ? / L W C
月份    1-12 或者 JAN-DEC    , - * /
星期    1-7 或者 SUN-SAT    , - * ? / L C #
年(可選)    留空, 1970-2099    , - * /

OK!我們看最後一個:UserTopFileJob
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    logger.info("Create User Top File Start");
    try {
      this.getUserTopService().createUserTopFile();//這個方法調用我們唯一講過的UserTopServiceImp中的那個方法,建立三個html文件!
    }
    catch (BbscsException ex) {
      logger.error(ex);
    }
    logger.info("Create User Top File End");
}
我們看看spring在applicationContext.xml中配置:
<bean name="userTopFileJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
   <value>
    com.laoer.bbscs.service.scheduling.UserTopFileJob
   </value>
</property>
<property name="jobDataAsMap">
   <map>
    <entry key="userTopService">
     <ref local="userTopService" />
    </entry>
   </map>
</property>
</bean>
<bean id="userTopFileJobCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
   <ref bean="userTopFileJob" />
</property>
<property name="cronExpression">
   <value>0 0 4 ? * 2</value>//星期二4點做事!天哪....
     </property>
</bean>
我們這樣就完成了大部分(主要)的業務邏輯的分析了,但對於JSP界面層和web中以action包爲主的web層我們仍然需要進行分析,以使我們的業務邏輯發揮作用!

發佈了76 篇原創文章 · 獲贊 4 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章