欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring boot基于ScheduledFuture实现定时任务

程序员文章站 2022-04-09 16:13:51
一、 背景  接,完成存储过程的动态生成后,需要构建定时任务执行存储过程二、 环境  1.此随笔内容基于spring boot项目  2.数据库为mysql 5.7.9版本  3.jdk 版本为1.8...

一、 背景

  接,完成存储过程的动态生成后,需要构建定时任务执行存储过程

二、 环境

  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);<br>  // 省略之前的...
}

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;
//省略其他处理
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。