1. 程式人生 > >Spring Task 定時器如何在專案啟動時一次性註冊多個定時器任務

Spring Task 定時器如何在專案啟動時一次性註冊多個定時器任務

使用情景:前面的一篇文章已經說明了如何通過外部訪問,在不停伺服器的情況下動態的修改cron引數值,從而達到動態的修改定時器的任務,有需要的可以參考文章: 動態修改引數cron的值來實現Spring自帶定時器動態的執行任務,但是還有一種情況就是能不能不是通過外部修改,而是直接在專案啟動的時候就已經註冊好所需的幾個定時器,答案是可以的,這可能就是因為Spring設計的一貫作風吧!
目的:一個系統下有多家公司,而每家公司的要執行定時任務的cron時間週期不一定會一樣,所以就需要將每家公司不同的cron週期寫在一個xml的配置檔案中,在專案啟動時讀取配置檔案獲得cron及每家公司唯一的公司編碼code,然後放在一個map集合中,然後通過Spring Task的多個觸發器註冊多個定時器任務;PS 為了測試是否能實現,我簡單的直接將cron與公司編碼存在一個map集合中了。最後測試是完全OK的,具體程式碼如下:

package timer;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

@Lazy(value=false)
@Component
@EnableScheduling
public class QuartzTask implements SchedulingConfigurer{
	private static Logger log = Logger.getLogger(QuartzTask.class);
	
	/**
	 * 註冊多個Spring Task的定時器任務,從而來執行多家公司不同的定時任務
	 */
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		taskRegistrar.setTriggerTasks(getManyTaskAndTrigger());		
	}
	
	/**
	 * 獲得多家公司code及多個不同的cron(定時器執行週期)
	 * @return
	 */
	public Map<String, String> getCompanyCodeAndCron(){
		Map<String, String> mapCodeAndCron = new HashMap<String, String>();
		mapCodeAndCron.put("A00000000", "0 46 11 22 3 4");
		mapCodeAndCron.put("B07550001", "0 47 11 22 3 4");
		mapCodeAndCron.put("C00210001", "0 48 11 22 3 4");
		return mapCodeAndCron;
	}
	
	/**
	 * 獲得多觸發器的多個定時任務的map集合
	 * @return
	 */
	public Map<Runnable, Trigger> getManyTaskAndTrigger(){
		Map<Runnable, Trigger> mapTask = new HashMap<Runnable, Trigger>();
		Map<String, String> mapStr = this.getCompanyCodeAndCron();
		//遍歷map集合
		for(Map.Entry<String, String> entry : mapStr.entrySet()){
			final String compCode = entry.getKey();
			final String cron = entry.getValue();
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					// 執行邏輯任務
					System.err.println("公司:編碼=" + compCode + "------cron時間週期=" + cron);
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					System.out.println("當前系統時間:" + sdf.format(System.currentTimeMillis()));
				}
			};
			Trigger trigger = new Trigger() {
				@Override
				public Date nextExecutionTime(TriggerContext triggerContext) {
					// 任務觸發,可修改任務的執行週期
					CronTrigger trigger = new CronTrigger(cron);
					Date nextExecutor = trigger.nextExecutionTime(triggerContext);
					return nextExecutor;
				}
			};
			mapTask.put(runnable, trigger);
		}
		return mapTask;
	}
	
	
}

執行後控制檯輸出資訊如下:


至此完畢,有不正之處還望多多指教!!!