spring自定義定時任務

技術 腦殘是治不好的 腦殘是治不好的 2017-09-26

spring自定義定時任務

首先來看看spring的定時任務的類結構

spring自定義定時任務

定時任務的相關類

Application是springboot的啟動類。

TimedTask是所有定時任務的接口

ResourceMakingTask是定時任務執行的線程池、定時任務的初始化管理的類。

NormalVideoMakingTask是一個具體的定時任務。

首先來看看 TimedTask 定時任務的接口類

import java.util.concurrent.ScheduledExecutorService;/*** 定時任務的接口*/public interface TimedTask extends Runnable { /** * 將定時任務提交到ScheduledThreadPool線程池中運行 * @param makingPool */ void addSelfToThreadPoolToRun(ScheduledExecutorService makingPool);}

繼承Runable接口,定時任務需要放到線程池中執行,需要實現一個Runnable接口

定義一個addSelfToThreadPoolToRun方法,定時任務如何添加到線程池,這個方法需要傳入一個線程池,就是執行這個定時任務的線程池,定時任務的延時、間隔時間等都是由這個方法來實現。

再來看看定時任務接口的一個實現類 NormalVideoMakingTask

import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;/*** 普通視頻製作的定時任務*/@Component//將bean交給spring管理public class NormalVideoMakingTask implements TimedTask { private static Logger log = LoggerFactory.getLogger(NormalVideoMakingTask.class); /** * 運行任務,添加定時邏輯 */ @Override public void addSelfToThreadPoolToRun(ScheduledExecutorService makingPool) { //任務1s後執行,執行完畢後休眠1s再重複執行 makingPool.scheduleWithFixedDelay(this,1,1, TimeUnit.SECONDS); } /** * 定時任務 的 任務業務邏輯。 */ @Override public void run() { log.debug("普通視頻製作定時任務:{}","開始"); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { log.error(e.getLocalizedMessage()); } log.debug("普通視頻製作定時任務:{}","完成"); }}

定時任務運行線程池的創建和任務的添加 ResourceMakingTask 類

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.core.env.Environment;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import javax.annotation.Resource;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

/**

* 資源製作任務啟動管理類 * 實現ApplicationContextAware接口是為了能得到spring的上下文 * 以便通過spring的上下文來得到所有的定時任務的bean批量啟動

*/

@Component

public class ResourceMakingTask implements ApplicationContextAware {

private static Logger log = LoggerFactory.getLogger(ResourceMakingTask.class);

/**

* spring上下文

*/

ApplicationContext applicationContext;

/**

* spingboot環境變量

*/

@Resource

Environment env;//springboot 的環境變量

/**

* 執行製作定時任務的線程池

*/

ScheduledExecutorService makingPool; //這個註解在spring創建完成此類時執行此方法

@PostConstruct

public void runTask(){

//初始化線程池

initMakingPool();

/*

使用一個新的線程來等待spring初始化結束

不阻塞spring的初始化過程

*/

makingPool.execute(new Runnable(){

@Override

public void run() {

try {

//延遲10s或更長,給於spring充分的時間,

//創建初始化所有的定時任務bean

TimeUnit.SECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

log.error(e.getLocalizedMessage());

}

//添加定時任務

addTimedTask();

}

});

}

/**

* 添加定時任務

*/

private void addTimedTask() {

//通過spring上下文獲取所有實現TimedTask接口的bean

Map<String, TimedTask> tasks = applicationContext.getBeansOfType(TimedTask.class);

Set<String> keys = tasks.keySet();

for(String timedTaskName : keys){

//將定時任務添加到線程池運行

tasks.get(timedTaskName).addSelfToThreadPoolToRun(makingPool);

log.debug("添加定時任務:{}",timedTaskName);

}

}

/**

* 初始化線程池

*/

private void initMakingPool() {

if (makingPool != null){

makingPool.shutdown();

}

String poolSizeStr = env.getProperty("makingTask.poolSize");

int poolSize = 1;

try {

poolSize = Integer.parseInt(poolSizeStr);

}catch (Exception e){

e.printStackTrace();

log.error(e.getLocalizedMessage());

}

makingPool = Executors.newScheduledThreadPool(poolSize);

}

/**

* 注入spring上下文

* @param applicationContext

* @throws BeansException

*/

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

this.applicationContext = applicationContext;

}

}