Spring boot基于ScheduledFuture实现定时任务

所属分类: 软件编程 / java 阅读数: 50
收藏 0 赞 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);<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;
//省略其他处理
}

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

更多精彩内容其他人还在看

SpringBoot中使用Ehcache的详细教程

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。这篇文章主要介绍了SpringBoot中使用Ehcache的相关知识,需要的朋友可以参考下
收藏 0 赞 0 分享

在idea 中添加和删除模块Module操作

这篇文章主要介绍了在idea 中添加和删除模块Module操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java spring整合junit操作(有详细的分析过程)

这篇文章主要介绍了java spring整合junit操作(有详细的分析过程),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解JAVA 弱引用

这篇文章主要介绍了 JAVA 弱引用的相关资料,帮助大家更好的理解和学习java引用对象,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

深入了解JAVA 虚引用

这篇文章主要介绍了JAVA 虚引用的相关资料,帮助大家更好的理解和学习JAVA,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

详解JAVA 强引用

这篇文章主要介绍了JAVA 强引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

java中的按位与(&)用法说明

这篇文章主要介绍了java中的按位与(&)用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
收藏 0 赞 0 分享

深入了解JAVA 软引用

这篇文章主要介绍了JAVA 软引用的相关资料,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

利用MyBatis实现条件查询的方法汇总

这篇文章主要给大家介绍了关于利用MyBatis实现条件查询的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用MyBatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享

Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.PathTranslator was bound

这篇文章主要介绍了Intellij IDEA 与maven 版本不符 Unable to import maven project See logs for details: No implementation for org.apache.maven.model.path.Pa
收藏 0 赞 0 分享
查看更多