Spring boot利用ScheduledFuture開啓定時任務

1、    背景html

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

2、    環境mysql

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

  2.數據庫爲mysql 5.7.9版本sql

  3.jdk 版本爲1.8數據庫

3、    說明app

  略 ide

4、    內容ui

  一、定義接口和接口參數bean;this

    1)在上一篇博客bean 的基礎上把接口配置參數bean修改一下,添加一個配置參數值和排序字段;在添加一個監測項的bean,想查看其餘的bean信息,請移步: java Spring動態生成Mysql存儲過程 

@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…
}

  

      二、定義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<String, Object>> mapList = new ArrayList<Map<String, Object>>(); // 新建任務信息集合
/**
 * 初始化監測項
 *
 * @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())) {
        List<QtInterface> InterList = qtInterfaceRepository.QueryInterFaceByItemId(qt.getId());
        if (InterList.size() > 0) {

            Map<String, Object> map_future = new HashMap<>();

            ScheduledFuture<?> future;// 監測任務
            List<QtInterfaceParameter> para = qtInterfaceParameterRepository.QueryInfoByInterId(InterList.get(0).getId()); // 查找參數信息
            List<String> map = 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 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("執行了過程:" +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<T> {
    private Integer result;
    private String msg;
    private T rows;
    private int total;
//省略其餘處理
}

  

5、    參考

    Spring Scheduled定時任務動態修改cron參數

    http://www.javashuo.com/article/p-qrbdgfyi-ex.html

    接口 java.util.concurrent.ScheduledFuture的使用

    https://www.runoob.com/manual/jdk1.6/java/util/concurrent/class-use/ScheduledFuture.html

相關文章
相關標籤/搜索