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

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

(0)

相关推荐

  • springboot schedule 解决定时任务不执行的问题

    @schedule 注解 是springboot 常用的定时任务注解,使用起来简单方便,但是如果定时任务非常多,或者有的任务很耗时,会影响到其他定时任务的执行,因为schedule 默认是单线程的,一个任务在执行时,其他任务是不能执行的.解决办法是重新配置schedule,改为多线程执行.只需要增加下面的配置类就可以了. import org.springframework.boot.autoconfigure.batch.BatchProperties; import org.springfr

  • SpringBoot实现动态定时任务

    项目情况: 在当前项目中需要一个定时任务来清除过期的校验码,如果使用数据库存储过程的话不方便维护.因此采用SpringBoot自带的方式来设置定时任务. 技术说明: SpringBoot自带的方式有两种可以实现: 一种是使用@Scheduled注解的方式,只需要在启动类或者它所在的类上添加@EnableScheduling注解允许执行定时任务,并且设置Schecduled注解的参数,诸如: 1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次 2.zone表示执行

  • springboot集成schedule实现定时任务

    背景 在项目开发过程中,我们经常需要执行具有周期性的任务.通过定时任务可以很好的帮助我们实现. 我们拿常用的几种定时任务框架做一个比较: 从以上表格可以看出,Spring Schedule框架功能完善,简单易用.对于中小型项目需求,Spring Schedule是完全可以胜任的. 1.springboot集成schedule 1.1 添加maven依赖包 由于Spring Schedule包含在spring-boot-starter基础模块中了,所有不需要增加额外的依赖. <dependenci

  • Spring Boot中配置定时任务、线程池与多线程池执行的方法

    配置基础的定时任务 最基本的配置方法,而且这样配置定时任务是单线程串行执行的,也就是说每次只能有一个定时任务可以执行,可以试着声明两个方法,在方法内写一个死循环,会发现一直卡在一个任务上不动,另一个也没有执行. 1.启动类 添加@EnableScheduling开启对定时任务的支持 @EnableScheduling @SpringBootApplication public class TestScheduledApplication extends SpringBootServletInit

  • SpringBoot基于数据库的定时任务统一管理的实现

    定时任务1 import lombok.extern.slf4j.Slf4j; /** * @author Created by niugang on 2019/12/24/15:29 */ @Slf4j public class TaskTest { public void task1() { log.info("反射调用测试[一]类"); } } 定时任务2 import lombok.extern.slf4j.Slf4j; /** * @author Created by niu

  • spring-boot通过@Scheduled配置定时任务及定时任务@Scheduled注解的方法

    串行的定时任务 @Component public class ScheduledTimer { private Logger logger = Logger.getLogger(this.getClass()); /** * 定时任务,1分钟执行1次,更新潜在客户超时客户共享状态 */ @Scheduled(cron="0 0/1 8-20 * * ?") public void executeUpdateCuTask() { Thread current = Thread.curr

  • Spring boot如何通过@Scheduled实现定时任务及多线程配置

    这篇文章主要介绍了Spring boot如何通过@Scheduled实现定时任务及多线程配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用@Scheduled 可以很容易实现定时任务 spring boot的版本 2.1.6.RELEASE package com.abc.demo.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spr

  • springBoot 创建定时任务过程详解

    前言 好几天没写了,工作有点忙,最近工作刚好做一个定时任务统计的,所以就将springboot 如何创建定时任务整理了一下. 总的来说,springboot创建定时任务是非常简单的,不用像spring 或者springmvc 需要在xml 文件中配置,在项目启动的时候加载.spring boot 使用注解的方式就可以完全支持定时任务. 不过基础注解的话,可能有的需求定时任务的时间会经常变动,注解就不好修改,每次都得重新编译,所以想将定时时间存在数据库,然后项目读取数据库执行定时任务,所以就有了基

  • 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") p

  • Quartz+Spring Boot实现动态管理定时任务

    项目实践过程中碰到一个动态管理定时任务的需求:针对每个人员进行信息的定时更新,具体更新时间可随时调整.启动.暂定等. 思路 将每个人员信息的定时配置保存到数据库中,这样实现了任务的动态展示和管理.任务的每一次新增或变更,都会去数据库变更信息. 设置一个统一的任务管理器,专门负责动态任务的增删改查. POM依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mav

  • Spring Boot集成ShedLock分布式定时任务的实现示例

    一.ShedLock是什么? 官方地址:github.com/lukas-kreca- 以下是ShedLock锁提供者,通过外部存储实现锁,由下图可知外部存储集成的库还是很丰富的 本篇教程我们基于JdbcTemplate存储为例来使用ShedLock锁. 二.落地实现 1.1 引入依赖包 shedlock所需依赖包: <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>she

  • Spring Boot下的Job定时任务

    编写Job定时执行任务十分有用,能解决很多问题,这次实习的项目里做了一下系统定时更新三方系统订单状态的功能,这里用到了Spring的定时任务使用的非常方便,下面总结一下如何使用: 一,@scheduled注解 @scheduled这个注解是定时任务的核心所在,在某个方法上面标记此注解,即为此方法设置定时调用,当然调用的频率时间还需要在cron中设置. 例如: @Scheduled(cron = "0 */10 * * * ? ") public void handleOrderStat

  • spring boot基于DRUID实现数据源监控过程解析

    这篇文章主要介绍了spring boot基于DRUID实现数据源监控过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 随着需求和技术的日益革新,spring boot框架是越来越流行,她也越来越多地出现在我们的项目中,当然最主要的原因还是因为spring boot构建项目实在是太爽了,构建方便,开发简单,而且效率高.今天我们并不是来专门学习spring boot项目的,我们要讲的是数据源的加密和监控,监控到好说,就是不监控也没什么问题,但

  • Spring Boot实现简单的定时任务

    前言 有时候在开发中经常会使用一些定时的任务,比如果整点推送,或者是每隔一段时间给客户发送一个消息等等.下面就来给大家介绍下Spring Boot实现简单的定时任务的相关内容. 创建定时任务类 每一分钟执行一次 @Component @EnableScheduling public class AllianceDiscountsActivityJob { @Autowired private AllianceDiscountsActivityService allianceDiscountsAc

  • Spring boot基于JPA访问MySQL数据库的实现

    本文展示如何通过JPA访问MySQL数据库. JPA全称Java Persistence API,即Java持久化API,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据,结合其他ORM的使用,能达到简化开发流程的目的,使开发者能够专注于实现自己的业务逻辑上. Spring boot结合Jpa 能够简化创建 JPA 数据访问层和跨存储的持久层功能,用户的持久层Dao接口只需要继承定义好的接口,无需再写实现类,就可以实现对象的CRUD操作以及分页排序等功能. 环境要求

  • Spring Boot 基于注解的 Redis 缓存使用详解

    看文本之前,请先确定你看过上一篇文章<Spring Boot Redis 集成配置>并保证 Redis 集成后正常可用,因为本文是基于上文继续增加的代码. 一.创建 Caching 配置类 RedisKeys.Java package com.shanhy.example.redis; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import org.springf

  • Spring Boot基于Active MQ实现整合JMS

    我们使用jms一般是使用spring-jms和activemq相结合,通过spring Boot为我们配置好的JmsTemplate发送消息到指定的目的地Destination.本文以点到点消息模式为例,演示如何在Spring Boot中整合 JMS 和 Active MQ ,实现 MQ 消息的生产与消费. 点到点消息模式定义:当消息发送者发送消息,消息代理获得消息后,把消息放入一个队列里,当有消息接收者来接收消息的时候,消息将从队列里取出并且传递给接收者,这时候队列里就没有此消息了.队列Que

  • spring boot基于注解的声明式事务配置详解

    事务配置 1.配置方式一 1)开启spring事务管理,在spring boot启动类添加注解@EnableTransactionManagement(proxyTargetClass = true):等同于xml配置方式的 <tx:annotation-driven />(注意:1项目中只需配置一次,2需要配置proxyTargetClass = true) 2)在项目中需要添加事务的类或方法上添加注解@Transactional(建议添加在方法上),一般使用默认属性即可,若要使用事务各属性

随机推荐