2011-09-20 17 views
2

我正在尋找一個lib,允許我做尋找持久性計時器的Spring應用程序

  1. 定義將一次在一個特定的時間在未來被調用的工人(不需要再像featrure時間表/ cron的),即一個定時器
  2. 工人應接受該枝條一些參數/輸入
  3. 所有應在DB(或文件)中的工人
  4. 工人應該由彈簧進行管理持久性的上下文 - - spring應該實例化worker,以便可以使用dependen注入資本投資者入境計劃
  5. 能夠通過API動態創建定時器並不僅僅是靜態通過Spring XML豆

不錯的:

  1. 支持集羣,即有多個節點可以承載一個工人。每家商店在中jobn數據庫將引起一個工作invokaction在點頭的一個

我已經研究幾個備選方案都不符合要求:

  • 石英

時使用org.springframework.scheduling.quartz.JobDetailBean使石英創建您的工人實例(而不是春天),所以你不能得到依賴注射,(這將導致我使用服務定位器,我想避免)

while using org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean while you can not get a context。你的工人暴露使用MethodInvokingJobDetailFactoryBean中不能使用持久性時,不接受任何arguments.In另外一個公共方法(形成的Javadoc)

注:通過這個FactoryBean創建JobDetails不是序列,因此不適合持續工作商店。您需要將您自己的Quartz Job實現爲每個需要持久作業委託給特定服務方法的情況的精簡包裝器。

  • Spring的計時器和簡單的JDK計時器不支持的持久性/集羣功能

我知道我可以使用DB和Spring(甚至JDK)定時器IMPL的事情我自己,但我更喜歡使用一個3r黨的lib。

有什麼建議嗎?

回答

3

如果你要創建的工作細節,以產生觸發/求職信息在運行時,仍然能夠使用Spring DI上的豆你可以參考this blog post,它顯示瞭如何與ObjectFactoryCreatingFactoryBean結合使用SpringBeanJobFactory使用Spring注入的bean在運行時創建Quartz觸發對象。

+1

正是我需要的。謝謝 –

0

你的要求3和4對我來說並沒有什麼意義:你怎麼能把整個包(工人+工作)序列化爲它神奇地醒來並且完成它的工作?運行系統中的某些東西是否應該在適當的時候進行操作?難道這不就是工作人員嗎?

我的方法是:創建一個Timer,Spring可以實例化並注入依賴項。然後這個定時器會從持久存儲中加載它的工作/任務,安排它們執行並執行它們。你的課程可以是圍繞java.util.Timer的包裝,而不是處理調度內容。您必須自己實現與羣集相關的邏輯,以便只有一個定時器/工作者可以執行該工作/任務。

+0

請注意,我需要每個工作只進行一次重複沒有調用。每個工人不改變其狀態(即jobDataMap)。從持久性POV我需要:存儲作業定義(何時觸發以及要做什麼)以及在調度期間不會調用的jobDataMap –

+0

您的計時器「bean」與DB一起可以強制執行單個執行。 「獲勝」計時器(即實際執行任務)被記錄在數據庫中,以防止其他計時器獲得任務;成功的任務執行也被記錄下來。其餘的確實取決於你的需求:定時器是否應該爲數據庫查詢新任務?新任務如何提交?當任務不按錯誤執行時應該發生什麼?其他定時器是否應該接管?該任務應該立即執行還是以後執行? – vagelis

0

對於那些對石英替代品感興趣的人,請看db-schedulerhttps://github.com/kagkarlsson/db-scheduler)。持久性任務/執行時間表保存在單個數據庫表中。保證只能由羣集中的調度程序執行一次。

  1. 是的,請參閱下面的代碼示例。

  2. 目前僅限於單個字符串標識符,無格式限制。調度程序可能會在未來得到擴展,併爲作業細節/參數提供更好的支持。

  3. 執行時間和上下文在數據庫中是持久的。計劃程序啓動時,將任務名稱綁定到工作人員。只要實現了接口,該工作人員就可以被Spring實例化。

  4. 參見3)。

  5. 是的,看下面的代碼示例。

代碼示例:

private static void springWorkerExample(DataSource dataSource, MySpringWorker mySpringWorker) { 

    // instantiate and start the scheduler somewhere in your application 
    final Scheduler scheduler = Scheduler 
      .create(dataSource) 
      .threads(2) 
      .build(); 
    scheduler.start(); 

    // define a task and a handler that named task, MySpringWorker implements the ExecutionHandler interface 
    final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task", mySpringWorker); 

    // schedule a future execution for the task with a custom id (currently the only form for context supported) 
    scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001")); 
} 


public static class MySpringWorker implements ExecutionHandler { 
    public MySpringWorker() { 
     // could be instantiated by Spring 
    } 

    @Override 
    public void execute(TaskInstance taskInstance, ExecutionContext executionContext) { 
     // called when the execution-time is reached 
     System.out.println("Executed task with id="+taskInstance.getId()); 
    } 
} 
+0

請添加免責聲明,您是作者。 – lexicore

相關問題