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

作者:qaqhat 时间:2023-04-20 15:59:58 

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 "更新失败!";
}
}

}

来源:https://blog.csdn.net/SSM1234/article/details/113607799

标签:springboot,动态,定时任务
0
投稿

猜你喜欢

  • 详解C语言实现猜数字游戏

    2023-11-03 04:58:51
  • java通过方向键控制小球移动的小游戏

    2023-11-10 05:25:59
  • Swagger及knife4j的基本使用详解

    2023-02-13 09:34:00
  • MyBatis环境资源配置实现代码详解

    2023-08-05 08:59:02
  • Android自定义TextView跑马灯效果

    2023-08-07 01:14:57
  • SpringBoot如何使用自定义注解实现接口限流

    2023-11-25 07:22:37
  • Flutter状态管理Bloc使用示例详解

    2023-08-24 09:09:10
  • Maven中的SnapShot版本和正式版本的区别

    2023-11-03 16:31:46
  • C++语言实现线性表之链表实例

    2023-06-20 22:21:20
  • Java基于zxing生成二维码矩阵过程解析

    2023-11-23 06:04:06
  • java中JVM中如何存取数据和相关信息详解

    2023-08-10 03:49:46
  • Java操作Mongodb数据库实现数据的增删查改功能示例

    2023-11-25 00:02:05
  • Android自定义attr的各种坑

    2023-07-12 06:11:50
  • 解决java.lang.ClassCastException的java类型转换异常的问题

    2023-11-29 04:34:10
  • IDEA + Maven环境下的SSM框架整合及搭建过程

    2023-08-26 02:06:55
  • Javassist之一秒理解java动态编程

    2023-11-09 09:36:33
  • 解决nacos升级spring cloud 2020.0无法使用bootstrap.yml的问题

    2021-12-02 19:44:29
  • java使用influxDB数据库的详细代码

    2023-03-04 05:22:27
  • Java的类型擦除式泛型详解

    2022-01-02 11:59:00
  • Quarkus的Spring扩展快速改造Spring项目

    2023-11-26 03:01:58
  • asp之家 软件编程 m.aspxhome.com