歡迎您光臨本站 註冊首頁

Spring boot基於ScheduledFuture實現定時任務

←手機掃碼閱讀     e36605 @ 2020-06-09 , reply:0

一、 背景

  接上一篇,完成存儲過程的動態生成後,需要構建定時任務執行存儲過程

二、 環境

  1.此隨筆內容基於spring boot項目

  2.數據庫為mysql 5.7.9版本

  3.jdk 版本為1.8

三、 內容

1、定義接口和接口參數bean;

    1)在上一篇博客bean 的基礎上把接口配置參數bean修改一下,添加一個配置參數值和排序字段;在添加一個監測項的bean,想查看其他的bean信息,請移步

  @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; // 標準值   private Integer fre_num;   private String frequency;   private String status;   private String warnType;   private String warn_date_num;// 監測頻次     //此處省略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; //參數名稱   private String explain_info; //參數描述   private String type;// 輸入輸出類型   private String paraType; // 參數類型   private Integer paraLen;  private Integer paraValue; // 參數值  private Integer order_num; // 排序字段     //此處省略get、set…  }

 

2、定義ScheduledFuture定時任務

1) 添加接口

  public interface TestService {    ResultInfo initMonitor(String Id);
  // 省略之前的...  }

 

2) 編寫實現類

  @Service  public class TestServiceImpl implements TestService {   @Autowired   private MonitorWarnItemRepository monitorWarnItemRepository   @Autowired   private ThreadPoolTaskScheduler threadPoolTaskScheduler;   @Bean   public ThreadPoolTaskScheduler threadPoolTaskScheduler() {    return new ThreadPoolTaskScheduler();   }  List<Map> mapList = new ArrayList<Map>(); // 新建任務信息集合  /**   * 初始化監測項   *   * @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;     }  /**   * 配置任務信息   *   * @param qt   * @return   */  private String buildTask(MonitorWarnItem qt) {    String msg = "";    if (IsFure(qt.getId())) {      ListInterList = qtInterfaceRepository.QueryInterFaceByItemId(qt.getId());      if (InterList.size() > 0) {           Mapmap_future = new HashMap<>();           ScheduledFuture future;// 監測任務        Listpara = qtInterfaceParameterRepository.QueryInfoByInterId(InterList.get(0).getId()); // 查找參數信息        Listmap = new ArrayList<>(para.size());        if (para.size() > 0) { // 參數集合          for (QtInterfaceParameter pa : para) {            for (int item = 1; item <= para.size(); item++) {              if (item == pa.getOrder_num()) { // 根據字段排序來設置參數值的順序                map.add(pa.getPara_value()); // 設置值                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()));// 初始化任務,第二個參數是Cron表達式          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 += " 監測項:" + qt.getProName() + " 監測頻次字段為空,不能執行計劃!";        }         } else {        msg += " 監測項:" + qt.getProName() + " 沒有查找到接口配置信息";         }    } else {      msg += " 監測項:" + qt.getProName() + " 已經啟動,請不要重複啟動。";    }    return msg;  }  }

 

3) 構建任務處理線程類

  public class QuartzTaskService implements Runnable {       private JdbcTemplate jdbcTemplate;    private String proName;    private Listmaplist;    private MonitorWarnItem item;    public QuartzTaskService(String proName,Listmaplist,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("執行了過程:" +proName+"當前參數順序:"+bf.toString()+ " 當前時間 "+ sdf.format(new Date()));    }    @Override    public void run() {      try {        executeInternal(); // 調用執行      } catch (JobExecutionException e) {        e.printStackTrace();      }    }

 

4) 此處是用的List保存的任務信息,在項目重啟之後這個東西就沒了,也就是說定時任務就全丟了,so,這裡考慮使用數據庫來持久化保存調度任務信息, 或者在項目啟動的時候寫一個配置來調用啟動定時任務

  @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");// 根據狀態查詢需要啟動的監測項      if(itemList.size()>0){ // 存在需要啟動的檢測項  For(MonitorWarnItem qt: itemList)        testService.initMonitor(qt);// 啟動任務列表和消息      }      return "";    }       @Override    public void run(String... args) throws Exception {      setTask ();    }  }

 

5)最後附上一個我使用的返回處理類

  public class ResultInfo{    private Integer result;    private String msg;    private T rows;    private int total;  //省略其他處理  }

 


[e36605 ] Spring boot基於ScheduledFuture實現定時任務已經有224次圍觀

http://coctec.com/docs/java/show-post-237665.html