springBoot項目集成quartz開發定時任務案例及註意事項
quartz下載、安裝
Quartz是完全由java開發的一個開源的任務日程管理系統,任務進度管理器就是一個在預先確定的時間到達時,負責執行(或者通知)一段程序或功能的系統,即定時執行某個任務
。
Quartz用一個小Java庫發佈文件(.jar文件),這個庫文件包含瞭所有Quartz核心功能。這些功能的主要接口(API)是Scheduler接口。它提供瞭簡單的操作,例如:將任務納入日程或者從日程中取消,開始/停止/暫停日程進度。
上圖是quartz服務涉及的11張表, 下面這個圖是maven中引入的quartz依賴包
Quartz的jar包下載、SpringBoot項目整合Quartz安裝及具體的使用方法本站已經有很多,但是還是建議參考W3CSchool的官方文檔 Quartz快速入門指南
官方文檔地址: https://www.w3cschool.cn/quartz_doc/quartz_doc-2put2clm.html
實戰案例
假如我開發環境已經配置好,我們隻關註具體業務實現。實際上做項目的過程中也很少會讓開發自己去集成組件,通常都是開發環境已經配置好瞭,如果需要配置的話還是像上面說的,看官方文檔吧。
現在有個需求是每天凌晨把某個登記表A的信息篩選後刷到B表中,先貼上代碼:
//RefreshTableJob.java的代碼 @Component("RefreshTableJob") public class RefreshTableJob { private static final Logger logger = LoggerFactory.getLogger(RefreshIdleAssetJob.class); public void PullData(){ try{ SpringUtils.getBean(IassetService.class).initIdleAssetList(); } catch (RestClientResponseException e) { logger.error("數據同步失敗,error:"+e.getMessage()); }catch (Exception e) { e.printStackTrace(); logger.error("數據同步失敗,error:"+e.getMessage()); } } }
//assetServiceImpl.java的代碼 實現瞭IassetService接口 @Service public class IdleAssetServiceImpl implements IaAssetService{ @Resource private IdleAssetMapper idleAssetMapper; /** * 拉取增量閑置資產數據 */ @Override @Transactional public void initIdleAssetList(){ // 處理閑置數據 List<HashMap> initList = idleAssetMapper.selectIdleList(null); while (initList != null && initList.size() > 0){ for(HashMap data : initList){ HashMap paramMap = new HashMap(); String uuid = UUID.randomUUID().toString().trim(); paramMap.put("UPDATETIME", DateUtils.getNowDate()); paramMap.put("UPDATEUSER", ""); paramMap.put("STATUS", data.get("A_STATUS")); // 。。。。這裡省略瞭很多字段 paramMap.put("USAGESECRET", data.get("A_USAGESECRET")); paramMap.put("BELONGENTITYID", data.get("A_ID")); idleAssetMapper.saveIdleAsset(paramMap); } initList = idleAssetMapper.selectEquipIdleList(null); } logger.info("設備儀器表閑置資產數據獲取完成");
RefreshTableJob.java就是定時任務執行的入口,它的主要邏輯是調用service實現類中的initIdleAssetList方法,調用Mybatis的mapper文件查詢數據庫表A的增量數據,循環處理後刷入B表,配置的cron表達式是 0 0 2 1/1 * ? * (每天兩天執行一次)。
常見問題及解決方案
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.bjsasc.openshare.idleasset.service.IassetService' available
原因:定時任務類RefreshTableJob中找不到IassetService這個類
解決方法:
在系統的啟動類的main方法中加上這麼一行配置信息,僅本地調試的時候加哦,這行代碼不用提交,生產環境沒有這個問題,不知道為啥子
System.setProperty(“spring.devtools.restart.enabled”, “false”);
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
直接原因:我在插入B表的時候看到有個創建人字段,想獲取系統中的當前登錄用戶信息,結果獲取不到request相關對象
相信查過資料的朋友看到瞭網上說的設置request子線程共享或者重新實現RequestAttributes接口的方式瞭,這倆方案隻是屏蔽報錯的,如果隻是想屏蔽報錯,那直接刪掉出錯位置的代碼或者寫個自定義接口實現類判斷一下requestAttributes 為空時new一個就完瞭。
那怎麼獲取當前登錄用戶呢?
答案是獲取不到,定時任務可以在不登陸系統的情況下運行,對於在controller層調用service方法(WEB訪問方式)中使用RequestContextHolder或者WebApplicationContext對象獲取上下文的情況完全沒有問題。但是除瞭controller層外,調度任務等也可能調用service層的方法(非web方式根本不存在request對象),這種情況下不能使用上下文對象獲取其中的用戶信息。
如果你非要娶,可以提前把用戶登錄信息存到redis或者其他渠道,看起來有點麻煩,真有這樣的需求嗎,showme探討一下。
到此這篇關於springBoot項目集成quartz開發定時任務案例及註意事項的文章就介紹到這瞭,更多相關springBoot集成quartz開發定時任務內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- springboot 啟動項目打印接口列表的實現
- SpringBoot2.6.3集成quartz的方式
- SpringBoot自動配置Quartz的實現步驟
- 詳解基於redis實現的四種常見的限流策略
- Spring Cloud Gateway Hystrix fallback獲取異常信息的處理