当前位置: 首页 > 编程笔记 >

springboot动态定时任务的实现方法示例

齐起运
2023-03-14
本文向大家介绍springboot动态定时任务的实现方法示例,包括了springboot动态定时任务的实现方法示例的使用技巧和注意事项,需要的朋友参考一下

1、maven引入quartz包

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
 <groupId>org.quartz-scheduler</groupId>
 <artifactId>quartz</artifactId>
 <version>2.3.2</version>
</dependency>

2、创建定时任务工厂类

/**
 * 定时任务工厂类
 */
@Component
public class JobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

 private transient AutowireCapableBeanFactory beanFactory;

 @Override
 protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
 final Object jobInstance = super.createJobInstance(bundle);
 beanFactory.autowireBean(jobInstance);
 return jobInstance;
 }

 @Override
 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
 this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
 }

}

3、创建定时任务抽象类

public abstract class AbstractTask implements Job {

 private Logger logger = LoggerFactory.getLogger(AbstractTask.class);

 protected abstract void executeInternal(JobExecutionContext context) throws Exception;

 /**
 * 定时任务标识
 */
 private String key;

 /**
 * 数据库里配置的主键id
 */
 private Long dataBaseId;

 @Override
 public void execute(JobExecutionContext context) {
 try {
  executeInternal(context);
 } catch (Exception e) {
  logger.error(e.getMessage(), e);
  logger.error("job execute failed!");
 }
 }

 public String getKey() {
 return key;
 }

 public void setKey(String key) {
 this.key = key;
 }

 public Long getDataBaseId() {
 return dataBaseId;
 }

 public void setDataBaseId(Long dataBaseId) {
 this.dataBaseId = dataBaseId;
 }
}

4、创建定时任务业务实现类

这里可以写你的业务代码,实现具体的业务逻辑。

@Component("JobTask")
public class JobTask extends AbstractTask {

 @Override
 protected void executeInternal(JobExecutionContext context) {
 System.out.println("key = " + this.getKey());
 System.out.println("dataBaseId = " + this.getDataBaseId());
 }

}

5、创建定时任务管理器

包括项目启动时添加定时任务,手动添加定时任务,更新定时任务,删除定时任务方法。

/**
 * 定时任务管理容器 component (单例模式)
 */
@Component
@Scope("singleton")
public class JobQuartzManager implements ApplicationContextAware {

 /**
 * 创建新的scheduler
 */
 private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

 private Scheduler scheduler;

 /**
 * 定义组名称,不同的组用于区分任务
 */
 private static final String JOB_GROUP_NAME = "JOB_GROUP_NAME";

 private static final String TRIGGER_GROUP_NAME = "TRIGGER_GROUP_NAME";

 /**
 * 日志
 */
 private Logger logger = LoggerFactory.getLogger(JobQuartzManager.class);

 private ApplicationContext applicationContext;

 @Autowired
 private JobFactory jobFactory;

 public void start() {
 //启动定时任务(初始化)
 try {
  this.scheduler = schedulerFactory.getScheduler();
  scheduler.setJobFactory(jobFactory); //设置定时任务工厂模式
  //项目启动时默认给spring容器添加动态的定时任务
  this.addJob("job" + 100L, 100L, JobTask.class, "0/2 * * * * ?");
 } catch (SchedulerException e) {
  logger.error(e.getMessage(), e);
  throw new RuntimeException("init Scheduler failed");
 }
 }

 public boolean addJob(String jobName, Long dataBaseId, Class jobClass, String cronExp) {
 boolean result = false;
 if (!CronExpression.isValidExpression(cronExp)) {
  logger.error("Illegal cron expression format({})", cronExp);
  return result;
 }
 try {
  JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_GROUP_NAME))
   .ofType((Class<AbstractTask>) Class.forName(jobClass.getName()))
   .build();
  //创建完jobDetail之后,使用语句传参数值,方便定时任务内部识别它是什么标识
  JobDataMap jobDataMap = jobDetail.getJobDataMap();
  jobDataMap.put("key", jobName);
  jobDataMap.put("dataBaseId", dataBaseId);
  Trigger trigger = TriggerBuilder.newTrigger()
   .forJob(jobDetail)
   .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
   .withIdentity(new TriggerKey(jobName, TRIGGER_GROUP_NAME))
   .build();
  scheduler.scheduleJob(jobDetail, trigger);
  scheduler.start();
  result = true;
 } catch (Exception e) {
  logger.error(e.getMessage(), e);
  logger.error("QuartzManager add job failed");
 }
 return result;
 }

 public boolean updateJob(String jobName, String cronExp) {
 boolean result = false;
 if (!CronExpression.isValidExpression(cronExp)) {
  logger.error("Illegal cron expression format({})", cronExp);
  return result;
 }
 JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
 TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME);
 try {
  if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  Trigger newTrigger = TriggerBuilder.newTrigger()
   .forJob(jobDetail)
   .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
   .withIdentity(new TriggerKey(jobName, TRIGGER_GROUP_NAME))
   .build();
  scheduler.rescheduleJob(triggerKey, newTrigger);
  result = true;
  } else {
  logger.error("update job name:{},group name:{} or trigger name:{},group name:{} not exists..",
   jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
  }
 } catch (SchedulerException e) {
  logger.error(e.getMessage(), e);
  logger.error("update job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
 }
 return result;
 }

 public boolean deleteJob(String jobName) {
 boolean result = false;
 JobKey jobKey = new JobKey(jobName, JOB_GROUP_NAME);
 try {
  if (scheduler.checkExists(jobKey)) {
  result = scheduler.deleteJob(jobKey);
  } else {
  logger.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
  }
 } catch (SchedulerException e) {
  logger.error(e.getMessage(), e);
  logger.error("delete job name:{},group name:{} failed!", jobKey.getName(), jobKey.getGroup());
 }
 return result;
 }

 @Override
 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
 this.applicationContext = applicationContext;
 }

}

6、创建定时任务启动类

项目运行时给spring注入定时任务

/**
 * 定时任务启动类
 */
@Component
public class JobRunner implements ApplicationRunner {

 //注入定时任务管理器
 @Autowired
 private JobQuartzManager quartzManager;

 /**
 * 项目启动时激活定时任务
 */
 @Override
 public void run(ApplicationArguments applicationArguments) {
 System.out.println("--------------------注入定时任务---------------------");
 quartzManager.start();
 System.out.println("--------------------定时任务注入完成---------------------");
 }

}

7、测试案例

@RestController
@RequestMapping("/job")
public class JobController {

 @Autowired
 JobQuartzManager quartzManager;

 @PostMapping("addJob")
 @ResponseBody
 public String addJob(@RequestParam("dataBaseId") Long dataBaseId, @RequestParam("cronExp") String cronExp){
 boolean success = quartzManager.addJob("job" + dataBaseId, dataBaseId, JobTask.class, cronExp);
 if(success){
  return "添加成功";
 }else{
  return "添加失败!";
 }
 }

 @PostMapping("deleteJob")
 @ResponseBody
 public String deleteJob(@RequestParam("jobName") String jobName){
 boolean success = quartzManager.deleteJob(jobName);
 if(success){
  return "删除成功";
 }else{
  return "删除失败!";
 }
 }

 @PostMapping("updateJob")
 @ResponseBody
 public String updateJob(@RequestParam("jobName") String jobName, @RequestParam("cronExp") String cronExp){
 boolean success = quartzManager.updateJob(jobName, cronExp);
 if(success){
  return "更新成功";
 }else{
  return "更新失败!";
 }
 }

}

总结

到此这篇关于springboot实现动态定时任务的文章就介绍到这了,更多相关springboot动态定时任务内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!

 类似资料:
  • 本文向大家介绍SpringBoot 实现定时任务的方法详解,包括了SpringBoot 实现定时任务的方法详解的使用技巧和注意事项,需要的朋友参考一下 一、定时任务实现的几种方式: Timer 这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。 Sch

  • 本文向大家介绍spring boot task实现动态创建定时任务的方法,包括了spring boot task实现动态创建定时任务的方法的使用技巧和注意事项,需要的朋友参考一下 在Spring Boot项目中,通过@EnableScheduling可启用Spring自带的定时任务支持,在通过@Scheduled注解定义定时任务,但是通过注解只能编写固定时间的定时任务,无法动态调整定时间隔,可通过

  • 本文向大家介绍SpringBoot执行定时任务@Scheduled的方法,包括了SpringBoot执行定时任务@Scheduled的方法的使用技巧和注意事项,需要的朋友参考一下 在做项目时,需要一个定时任务来接收数据存入数据库,后端再写一个接口来提供该该数据的最新的那一条。 数据保持最新:设计字段sign的值(0,1)来设定是否最新 定时任务插入数据:首先进行更新,将所有为1即新数据设置过期,然

  • 本文向大家介绍浅谈SpringBoot集成Quartz动态定时任务,包括了浅谈SpringBoot集成Quartz动态定时任务的使用技巧和注意事项,需要的朋友参考一下 SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling 为什么要使用Quartz 多任务情况下,quart

  • 本文向大家介绍PHP实现定时执行任务的方法,包括了PHP实现定时执行任务的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP实现定时执行任务的方法,代码简单实用。分享给大家供大家参考。 具体实现方法如下: 希望本文所述对大家的PHP程序设计有所帮助。

  • 本文向大家介绍SpringBoot整合SpringTask实现定时任务的流程,包括了SpringBoot整合SpringTask实现定时任务的流程的使用技巧和注意事项,需要的朋友参考一下 半藏商城中会有一些用户提交了订单但是一直没有支付的情况,之前我是通过quartz定时任务每天的5点扫描未支付订单然后读取用户的邮箱地址发送邮件提醒用户尽快支付。这次我是采用Spring中自带的SpringTask