Spring boot基于ScheduledFuture實(shí)現(xiàn)定時(shí)任務(wù)
一、 背景
接上一篇,完成存儲(chǔ)過程的動(dòng)態(tài)生成后,需要構(gòu)建定時(shí)任務(wù)執(zhí)行存儲(chǔ)過程
二、 環(huán)境
1.此隨筆內(nèi)容基于spring boot項(xiàng)目
2.數(shù)據(jù)庫為mysql 5.7.9版本
3.jdk 版本為1.8
三、 內(nèi)容
1、定義接口和接口參數(shù)bean;
1)在上一篇博客bean 的基礎(chǔ)上把接口配置參數(shù)bean修改一下,添加一個(gè)配置參數(shù)值和排序字段;在添加一個(gè)監(jiān)測(cè)項(xiàng)的bean,想查看其他的bean信息,請(qǐng)移步
@Entity
@Table(name="monitor_warn_item")
public class MonitorWarnItem {
@Id
private String id;
private String proName;//名稱
private String rule;
private String send_content;
private String recommend_value;// 建議值
private String standard_value; // 標(biāo)準(zhǔn)值
private Integer fre_num;
private String frequency;
private String status;
private String warnType;
private String warn_date_num;// 監(jiān)測(cè)頻次
//此處省略get、set…
}
@Entity
@Table(name="qt_interface_parameter")
public class QtInterfaceParameter {
@Id
private String id;
@Column(name="inter_id")
private String interId;
private String name; //參數(shù)名稱
private String explain_info; //參數(shù)描述
private String type;// 輸入輸出類型
private String paraType; // 參數(shù)類型
private Integer paraLen;
private Integer paraValue; // 參數(shù)值
private Integer order_num; // 排序字段
//此處省略get、set…
}
2、定義ScheduledFuture定時(shí)任務(wù)
1) 添加接口
public interface TestService {
ResultInfo initMonitor(String Id);<br> // 省略之前的...
}
2) 編寫實(shí)現(xiàn)類
@Service
public class TestServiceImpl implements TestService {
@Autowired
private MonitorWarnItemRepository monitorWarnItemRepository
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>(); // 新建任務(wù)信息集合
/**
* 初始化監(jiān)測(cè)項(xiàng)
*
* @param Id
* @return
*/
@Override
@Transactional
public ResultInfo initMonitor(String Id) {
ResultInfo info = new ResultInfo();
String msg = "";
MonitorWarnItem item = monitorWarnItemRepository.findId(Id);
msg =buildTask(item);
info.setResult(1);
info.setMsg("初始化成功,初始化返回信息:" + msg);
System.out.println(msg);// 日志打印
return info;
}
/**
* 配置任務(wù)信息
*
* @param qt
* @return
*/
private String buildTask(MonitorWarnItem qt) {
String msg = "";
if (IsFure(qt.getId())) {
List<QtInterface> InterList = qtInterfaceRepository.QueryInterFaceByItemId(qt.getId());
if (InterList.size() > 0) {
Map<String, Object> map_future = new HashMap<>();
ScheduledFuture<?> future;// 監(jiān)測(cè)任務(wù)
List<QtInterfaceParameter> para = qtInterfaceParameterRepository.QueryInfoByInterId(InterList.get(0).getId()); // 查找參數(shù)信息
List<String> map = new ArrayList<>(para.size());
if (para.size() > 0) { // 參數(shù)集合
for (QtInterfaceParameter pa : para) {
for (int item = 1; item <= para.size(); item++) {
if (item == pa.getOrder_num()) { // 根據(jù)字段排序來設(shè)置參數(shù)值的順序
map.add(pa.getPara_value()); // 設(shè)置值
item++;
}
}
}
}
QuartzTaskService service = new QuartzTaskService(InterList.get(0).getName(), map, jdbcTemplate, qt);
if (!"".equals(qt.getWarn_date_num()) && qt.getWarn_date_num() != null) {
future = threadPoolTaskScheduler.schedule(service, new CronTrigger(qt.getWarn_date_num()));// 初始化任務(wù),第二個(gè)參數(shù)是Cron表達(dá)式
if (future != null) {
map_future.put("future", future);
map_future.put("id", InterList.get(0).getItemId());
map_future.put("status", "0");
mapList.add(map_future);
}
} else {
msg += " 監(jiān)測(cè)項(xiàng):" + qt.getProName() + " 監(jiān)測(cè)頻次字段為空,不能執(zhí)行計(jì)劃!";
}
} else {
msg += " 監(jiān)測(cè)項(xiàng):" + qt.getProName() + " 沒有查找到接口配置信息";
}
} else {
msg += " 監(jiān)測(cè)項(xiàng):" + qt.getProName() + " 已經(jīng)啟動(dòng),請(qǐng)不要重復(fù)啟動(dòng)。";
}
return msg;
}
}
3) 構(gòu)建任務(wù)處理線程類
public class QuartzTaskService implements Runnable {
private JdbcTemplate jdbcTemplate;
private String proName;
private List<String> maplist;
private MonitorWarnItem item;
public QuartzTaskService(String proName,List<String> maplist,JdbcTemplate jdbcTemplate ,MonitorWarnItem item){
this.proName=proName;
this.maplist=maplist;
this.jdbcTemplate=jdbcTemplate;
this.item=item;
}
protected void executeInternal() throws JobExecutionException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
StringBuffer bf=new StringBuffer();
bf.append("call ");
bf.append(proName);
bf.append("(");
int i=1;
for(String map:maplist){
if(i==maplist.size()){ // 最后一位
bf.append("'"+map+"')");
}else {
bf.append("'" + map + "',");
}
i++;
}
jdbcTemplate.batchUpdate(bf.toString());
System.out.println("執(zhí)行了過程:" +proName+"當(dāng)前參數(shù)順序:"+bf.toString()+ " 當(dāng)前時(shí)間 "+ sdf.format(new Date()));
}
@Override
public void run() {
try {
executeInternal(); // 調(diào)用執(zhí)行
} catch (JobExecutionException e) {
e.printStackTrace();
}
}
4) 此處是用的List保存的任務(wù)信息,在項(xiàng)目重啟之后這個(gè)東西就沒了,也就是說定時(shí)任務(wù)就全丟了,so,這里考慮使用數(shù)據(jù)庫來持久化保存調(diào)度任務(wù)信息, 或者在項(xiàng)目啟動(dòng)的時(shí)候?qū)懸粋€(gè)配置來調(diào)用啟動(dòng)定時(shí)任務(wù)
@Component
@Order(1)
public class StartTask implements CommandLineRunner {
@Autowired
private TestService testService;
public String setTask(){
Calendar cale = null;
cale = Calendar.getInstance();
int year = cale.get(Calendar.YEAR);
MonitorWarnItem itemList=testService.QueryByStatus ("1");// 根據(jù)狀態(tài)查詢需要啟動(dòng)的監(jiān)測(cè)項(xiàng)
if(itemList.size()>0){ // 存在需要啟動(dòng)的檢測(cè)項(xiàng)
For(MonitorWarnItem qt: itemList)
testService.initMonitor(qt);// 啟動(dòng)任務(wù)列表和消息
}
return "";
}
@Override
public void run(String... args) throws Exception {
setTask ();
}
}
5)最后附上一個(gè)我使用的返回處理類
public class ResultInfo<T> {
private Integer result;
private String msg;
private T rows;
private int total;
//省略其他處理
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot定時(shí)任務(wù)參數(shù)運(yùn)行代碼實(shí)例解析
- SpringBoot整合SpringTask實(shí)現(xiàn)定時(shí)任務(wù)的流程
- Spring Boot @Scheduled定時(shí)任務(wù)代碼實(shí)例解析
- SpringBoot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)的方法
- Spring Boot監(jiān)聽Redis Key失效事件實(shí)現(xiàn)定時(shí)任務(wù)的示例
- springboot實(shí)現(xiàn)多實(shí)例crontab搶占定時(shí)任務(wù)(實(shí)例代碼)
- SpringBoot基于數(shù)據(jù)庫的定時(shí)任務(wù)統(tǒng)一管理的實(shí)現(xiàn)
- Spring Boot定時(shí)任務(wù)單線程多線程實(shí)現(xiàn)代碼解析
相關(guān)文章
java的socket請(qǐng)求和響應(yīng)方式
這篇文章主要介紹了java的socket請(qǐng)求和響應(yīng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
Java Runtime類詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Runtime類封裝了運(yùn)行時(shí)的環(huán)境。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接。下面通過本文給大家分享Java Runtime類詳解,需要的朋友參考下吧2017-04-04
Springboot項(xiàng)目中kaptcha驗(yàn)證碼的使用方式
這篇文章主要介紹了Springboot項(xiàng)目中kaptcha驗(yàn)證碼的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
基于javascript實(shí)現(xiàn)獲取最短路徑算法代碼實(shí)例
這篇文章主要介紹了基于javascript實(shí)現(xiàn)獲取最短路徑算法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
java實(shí)現(xiàn)word文件轉(zhuǎn)html文件
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)word文件轉(zhuǎn)html文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
將字符串?dāng)?shù)字格式化為樣式1,000,000,000的方法
這篇文章主要介紹了將字符串?dāng)?shù)字格式化為樣式1,000,000,000的方法,有需要的朋友可以參考一下2014-01-01
spring cloud gateway轉(zhuǎn)發(fā)服務(wù)報(bào)錯(cuò)的解決
這篇文章主要介紹了spring cloud gateway轉(zhuǎn)發(fā)服務(wù)報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Spring-data-JPA使用時(shí)碰到的問題以及解決方案
這篇文章主要介紹了Spring-data-JPA使用時(shí)碰到的問題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
關(guān)于ArrayList初始創(chuàng)建設(shè)定長(zhǎng)度問題
在使用ArrayList時(shí),初始化長(zhǎng)度并不等同于直接設(shè)定數(shù)組大小,如通過構(gòu)造函數(shù)指定長(zhǎng)度,僅僅是在內(nèi)部開辟了相應(yīng)的存儲(chǔ)空間,并不會(huì)改變ArrayList的實(shí)際元素個(gè)數(shù),即size屬性仍然為0,因此,嘗試直接訪問未實(shí)際添加元素的位置會(huì)引發(fā)異常2024-11-11

