国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Quartz中擴展MethodInvokingJobDetailFactoryBean實現(xiàn)...

利用Quartz來實現(xiàn)對任務(wù)的調(diào)度已經(jīng)被廣泛地應(yīng)用了,一個利用Quartz來進行任務(wù)調(diào)度的典型配置如下:

  1. <bean id="testTask" class="com.alisoft.xx.TestTask" />   
  2. <bean id="xxJobDetail"    
  3.     class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">   
  4.     <property name="concurrent">   
  5.         <value>false</value>   
  6.     </property>   
  7.     <property name="targetObject">   
  8.         <ref bean="testTask"/>   
  9.     </property>   
  10.     <property name="targetMethod">   
  11.         <value>execute</value>   
  12.     </property>   
  13. </bean>   
  14. <!-- SimpleTriggerBean可以用org.springframework.scheduling.quartz.CronTriggerBean代替 -->   
  15. <bean id="xxTriggerBean" class="org.springframework.scheduling.quartz.SimpleTriggerBean">   
  16.     <property name="jobDetail">   
  17.         <ref bean="xxJobDetail"/>   
  18.     </property>   
  19.     <property name="startDelay">   
  20.         <value>1000</value>   
  21.     </property>   
  22.     <property name="repeatInterval">   
  23.         <value>60000</value>   
  24.     </property>   
  25. </bean>   
  26. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">   
  27.     <property name="triggers">   
  28.         <list>   
  29.             <ref local="xxTriggerBean"/>   
  30.         </list>   
  31.     </property>   
  32. </bean>  

 

若有多個任務(wù)需要調(diào)度,則配置多個JobDetail、Trigger即可,待執(zhí)行的Task bean沒有啥任何要求,不需要extends任何class、或者implements任何interface,只是被執(zhí)行的method需要是無參數(shù)的;

但是在我們現(xiàn)實項目中,僅僅完成這樣的功能是還不夠的,我們還需要爭取完成以下幾點:

  1. 對所有的Task實現(xiàn)執(zhí)行開始、結(jié)束時間的記錄;
  2. 對每天的Task執(zhí)行結(jié)果持久化、或者通過email、旺旺消息等方式告知相關(guān)owner;
  3. 當我們有多臺Task服務(wù)器時,如何保證每個任務(wù)只在一臺服務(wù)器上執(zhí)行;

針對以上幾個問題,我們也都有很簡單、直接的辦法可以搞定,比如說1、2兩點可以直接在每個任務(wù)中各自編碼完成,但是這樣不僅每個task都要寫非常類似的重復(fù)代碼、而且不能保證每個任務(wù)的執(zhí)行情況都被記錄,因為某些task的編碼人員就不會在意這些非功能性需求;對于第3點,我們也可以通過配置來完成向不同task服務(wù)器部署不一樣的發(fā)布包來完成,但這給發(fā)布帶來了麻煩,這意味著有多少臺task服務(wù)器,就需要通過修改配置重新打包并發(fā)布多少次;

其實我們可以利用Spring默認提供的AOP來非常優(yōu)雅的解決這幾個問題:擴展MethodInvokingJobDetailFactoryBean來實現(xiàn)對任務(wù)調(diào)度時的攔截!其關(guān)鍵代碼為MethodInvokingJobDetailFactoryBean.MethodInvokingJob.executeInternal(JobExecutionContext context);這個method中;

具體步驟如下:

  1. 新增所有Task都需要實現(xiàn)的interface,可參考如下代碼:
    1. public interface TaskHandler {   
    2.     /**  
    3.      * 任務(wù)調(diào)度執(zhí)行需要實現(xiàn)的method  
    4.      */  
    5.     TaskResult execute();   
    6. }  
  2. 基于MethodInvokingJobDetailFactoryBean實現(xiàn)自定義的JobDetailFactoryBean,在具體執(zhí)行待調(diào)度任務(wù)的method前后加入公用邏輯,比如記錄開始、結(jié)束日期、判斷該task是否由該臺服務(wù)器執(zhí)行、任務(wù)執(zhí)行完成之后將運行結(jié)果進行持久化或者發(fā)email等給相關(guān)owner;可參考如下代碼:
    1. public class AppsMethodInvokingJobDetailFactoryBean extends  
    2.         MethodInvokingJobDetailFactoryBean {   
    3.     protected static final Log logger = LogFactory.getLog(AppsMethodInvokingJobDetailFactoryBean.class);   
    4.        
    5.     /* (non-Javadoc)  
    6.      * @see org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean#afterPropertiesSet()  
    7.      */  
    8.     @Override  
    9.     public void afterPropertiesSet() throws ClassNotFoundException,   
    10.             NoSuchMethodException {   
    11.         super.afterPropertiesSet();   
    12.            
    13.         logger.info("origin jobClass : " + ((JobDetail)super.getObject()).getJobClass().getName());   
    14.         // Consider the concurrent flag to choose between stateful and stateless job.   
    15.         if(MethodInvokingJob.class.getName().equals(((JobDetail)super.getObject()).getJobClass().getName())) {   
    16.             ((JobDetail)super.getObject()).setJobClass(AppsMethodInvokingJob.class);   
    17.         } else {   
    18.             ((JobDetail)super.getObject()).setJobClass(AppsStatefulMethodInvokingJob.class);   
    19.         }   
    20.         logger.info("new jobClass : " + ((JobDetail)super.getObject()).getJobClass().getName());   
    21.     }   
    22.   
    23.     public static class AppsMethodInvokingJob extends MethodInvokingJob {   
    24.         protected static final Log logger = LogFactory.getLog(AppsMethodInvokingJob.class);   
    25.         private MethodInvoker methodInvoker;   
    26.         private String errorMessage;   
    27.   
    28.         /**  
    29.          * Set the MethodInvoker to use.  
    30.          */  
    31.         public void setMethodInvoker(MethodInvoker methodInvoker) {   
    32.             this.methodInvoker = methodInvoker;   
    33.             this.errorMessage = "Could not invoke method '" + this.methodInvoker.getTargetMethod() +   
    34.                     "' on target object [" + this.methodInvoker.getTargetObject() + "]";   
    35.         }   
    36.   
    37.         /**  
    38.          * Invoke the method via the MethodInvoker.  
    39.          */  
    40.         protected void executeInternal(JobExecutionContext context) throws JobExecutionException {   
    41.             Date startDate = new Date();   
    42.             String taskName = methodInvoker.getTargetClass().getName();   
    43.             TaskResult taskResult;   
    44.             try {   
    45.                 if (logger.isInfoEnabled()) {   
    46.                     logger.info(taskName + " job start at " + startDate);   
    47.                 }   
    48.                    
    49.                 //根據(jù)當前服務(wù)器主機名或者IP判斷是否需要執(zhí)行該任務(wù)   
    50.                 //TODO Code   
    51.                    
    52.                 //調(diào)用具體task執(zhí)行method代碼   
    53.                 taskResult = this.methodInvoker.invoke();                  
    54.             } catch (Exception ex) {   
    55.                 logger.error(taskName + " accounted a error : " + this.errorMessage, ex);   
    56.                 throw new JobExecutionException(this.errorMessage, ex, false);   
    57.             } finally {   
    58.                 if(logger.isInfoEnabled()) {   
    59.                     logger.info(taskName + " job end   at " + new Date());   
    60.                 }   
    61.                    
    62.                 //將task執(zhí)行結(jié)果taskResult進行持久化、或者通知相關(guān)owner   
    63.                 //TODO Code   
    64.             }   
    65.         }   
    66.     }   
    67.   
    68.     public static class AppsStatefulMethodInvokingJob extends AppsMethodInvokingJob {   
    69.     }   
    70. }  
  3. 將自定義JobDetailFactoryBean的bean配置設(shè)置為abstract,從而減少每個task的相關(guān)配置量,新的代碼可參考如下配置:
    1. <bean id="appsAbstractJobDetail" class="com.alisoft...AppsMethodInvokingJobDetailFactoryBean"  
    2.     abstract="true">   
    3.     <property name="concurrent" value="false" />   
    4.     <property name="targetMethod" value="execute" />   
    5. </bean>   
    6. <bean id="testTaskHandler" class="com.alisoft...task.TestTaskHandler" />   
    7. <bean id="testTaskJobDetail" parent="appsAbstractJobDetail">         
    8.     <property name="targetObject" ref="testTaskHandler" />   
    9. </bean>   
    10. <bean id="testTaskTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">   
    11.     <property name="jobDetail" ref="testTaskJobDetail" />   
    12.     <property name="cronExpression" value="0 10 0 * * ?" />   
    13. </bean>  
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
解決Spring中使用quartz發(fā)生NotSerializableException methodInvoker的問題
Spring中定時任務(wù)Quartz集群配置學(xué)習(xí)
項目中定時任務(wù)多個如何實現(xiàn)
Spring 定時任務(wù)
Spring 定時器
Spring Quartz如何動態(tài)配置時間
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服