Spring boot基于ScheduledFuture实现定时任务

时间:2021-05-20

一、 背景

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

二、 环境

  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) 编写实现类

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

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

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章