Spring boot基于ScheduledFuture实现定时任务

网友投稿 280 2022-12-05


Spring boot基于ScheduledFuture实现定时任务

一、 背景

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

二、 环境

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> mapList = new ArrayList>(); // 新建任务信息集合

/**

* 初始化监测项

*

* @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 InterList = qtInterfaceRepository.QueryInterFaceByItemId(qt.getId());

if (InterList.size() > 0) {

Map map_future = new HashMap<>();

ScheduledFuture> future;// 监测任务

List para = qtInterfaceParameterRepository.QueryInfoByInterId(InterList.get(0).getId()); // 查找参数信息

List 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 maplist;

private MonitorWarnItem item;

public QuartzTaskService(String proName,List 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 {

private Integer result;

private String msg;

private T rows;

private int total;

//省略其他处理

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java Spring动态生成Mysql存储过程详解
下一篇:Java 创建并应用PPT幻灯片母版的方法示例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~