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);<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;
//省略其他处理
}
以上是 Spring boot基于ScheduledFuture实现定时任务 的全部内容, 来源链接: utcz.com/z/323221.html