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

 更新时间:2021年2月6日 00:00  点击:1825

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动态定时任务内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • ps动态环绕动画效果怎么制作

    ps动态环绕动画效果是现在很多人都非常喜欢的,大多数人还不知道ps动态环绕动画效果怎么制作下面文章就给大家介绍下ps怎么制作科技感十足的动态环绕动画效果,一起来看看...2017-07-06
  • 解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题

    这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28
  • vue 实现动态路由的方法

    这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • 详解springBoot启动时找不到或无法加载主类解决办法

    这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
  • Vue实现动态查询规则生成组件

    今天我们来给大家介绍下在Vue开发中我们经常会碰到的一种需求场景,本文主要介绍了Vue动态查询规则生成组件,需要的朋友们下面随着小编来一起学习学习吧...2021-05-27
  • SpringBoot集成Redis实现消息队列的方法

    这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
  • 解决Springboot get请求是参数过长的情况

    这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
  • Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
  • c#动态调用Webservice的两种方法实例

    这篇文章介绍了c#动态调用Webservice的两种方法实例,有需要的朋友可以参考一下...2020-06-25
  • Spring Boot项目@RestController使用重定向redirect方式

    这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • springBoot 项目排除数据库启动方式

    这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
  • SQL Server中执行动态SQL

    本文详细讲解了SQLServer中执行动态SQL的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2022-05-19
  • C#中动态显示当前系统时间的实例方法

    想在网页中动态地显示当前系统的时间,找了好多,不过都是一些停在那里不动的。。。不过皇天不负有心人,终于让我找到了...2020-06-25
  • jQuery为动态生成的select元素添加事件的方法

    下面小编就为大家带来一篇jQuery为动态生成的select元素添加事件的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-09-01
  • springboot中使用@Transactional注解事物不生效的坑

    这篇文章主要介绍了springboot中使用@Transactional注解事物不生效的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26
  • jQuery动态添加与删除tr行实例代码

    最近由于项目的需要,需要动态的添加和删除table中的tr,感觉用JS可以实现,但是在网上找了一下,单纯的自己写JS,感觉太麻烦,而且也不好维护。于是想到了最近学的jQuery。这篇文章给大家用实例介绍了jQuery动态添加与删除tr行的方法,有需要的朋友们可以参考借鉴。...2016-10-20
  • SpringBoot接口接收json参数解析

    这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
  • 详解SpringBoot之访问静态资源(webapp...)

    这篇文章主要介绍了详解SpringBoot之访问静态资源(webapp...),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-14
  • springboot多模块包扫描问题的解决方法

    这篇文章主要介绍了springboot多模块包扫描问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16