Springboot 通过Schedule实现定时任务动态读取执行(从数据库读取)

前言:1、利用反射机制实现。

           2、通过实现SchedulingConfigurer来配置定时任务。

           3、此种方式只能实现项目启动时,定时任务执行,不能再项目启动后开启、暂停任务。

效果:

        数据库中配置了2个任务(状态都是开启的,如果不想执行某条任务,可以将状态改为1)

 

表结构:

 
  1. CREATE TABLE `schedule_setting` (

  2. `id` int(11) NOT NULL AUTO_INCREMENT,

  3. `job_name` varchar(255) DEFAULT NULL,

  4. `class_name` varchar(255) DEFAULT NULL,

  5. `method` varchar(255) DEFAULT NULL,

  6. `cron` varchar(255) DEFAULT NULL,

  7. `status` int(2) DEFAULT NULL COMMENT '0 代表开启,1代表关闭',

  8. PRIMARY KEY (`id`)

  9. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

项目启动后开启执行,数据库中定义的2个方法

代码实现:

任务实体

 
  1. /**

  2. * @author : 徐长城

  3. * @des:

  4. * @date : 2019/8/20 21:37

  5. */

  6. public class ScheduleConfig {

  7. private Long id;

  8.  
  9. private String jobName;

  10.  
  11. private String className;

  12.  
  13. private String method;

  14.  
  15. private String cron;

  16.  
  17. public Long getId() {

  18. return id;

  19. }

  20.  
  21. public void setId(Long id) {

  22. this.id = id;

  23. }

  24.  
  25. public String getJobName() {

  26. return jobName;

  27. }

  28.  
  29. public void setJobName(String jobName) {

  30. this.jobName = jobName;

  31. }

  32.  
  33. public String getClassName() {

  34. return className;

  35. }

  36.  
  37. public void setClassName(String className) {

  38. this.className = className;

  39. }

  40.  
  41. public String getMethod() {

  42. return method;

  43. }

  44.  
  45. public void setMethod(String method) {

  46. this.method = method;

  47. }

  48.  
  49. public String getCron() {

  50. return cron;

  51. }

  52.  
  53. public void setCron(String cron) {

  54. this.cron = cron;

  55. }

  56. }

Dao以及xml

Springboot获取bean

 
  1. /**

  2. * @author : 徐长城

  3. * @des: 获取bean

  4. * @date : 2019/8/20 21:59

  5. */

  6. @Component

  7. public class ApplicationContextHelper implements ApplicationContextAware {

  8.  
  9. private static ApplicationContext applicationContext;

  10.  
  11. public ApplicationContextHelper() {

  12. }

  13.  
  14. @Override

  15. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

  16. ApplicationContextHelper.applicationContext = applicationContext;

  17. }

  18.  
  19. public static Object getBean(String beanName) {

  20. return applicationContext != null?applicationContext.getBean(beanName):null;

  21. }

  22. }

定时配置

 
  1. /**

  2. * @author : 徐长城

  3. * @des:

  4. * @date : 2019/8/20 21:43

  5. */

  6. @Component

  7. public class ScheduleSetting implements SchedulingConfigurer {

  8.  
  9. @Autowired

  10. private ScheduleDao scheduleDao;

  11.  
  12. @Override

  13. public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {

  14. // 获取所有任务

  15. List<ScheduleConfig> scheduleList = scheduleDao.getScheduleList();

  16. System.out.println(scheduleList.size());

  17. for (ScheduleConfig s : scheduleList){

  18. scheduledTaskRegistrar.addTriggerTask(getRunnable(s), getTrigger(s));

  19. }

  20. }

  21.  
  22.  
  23. /**

  24. * 转换首字母小写

  25. *

  26. * @param str

  27. * @return

  28. */

  29. public static String lowerFirstCapse(String str) {

  30. char[] chars = str.toCharArray();

  31. chars[0] += 32;

  32. return String.valueOf(chars);

  33. }

  34.  
  35. /**

  36. * runnable

  37. * @param scheduleConfig

  38. * @return

  39. */

  40. private Runnable getRunnable(ScheduleConfig scheduleConfig){

  41. return new Runnable() {

  42. @Override

  43. public void run() {

  44. Class<?> clazz;

  45. try {

  46. clazz = Class.forName(scheduleConfig.getClassName());

  47. String className = lowerFirstCapse(clazz.getSimpleName());

  48. Object bean = (Object) ApplicationContextHelper.getBean(className);

  49. Method method = ReflectionUtils.findMethod(bean.getClass(), scheduleConfig.getMethod());

  50. ReflectionUtils.invokeMethod(method, bean);

  51. } catch (ClassNotFoundException e) {

  52. e.printStackTrace();

  53. }

  54. }

  55. };

  56. }

  57.  
  58. /**

  59. * Trigger

  60. * @param scheduleConfig

  61. * @return

  62. */

  63. private Trigger getTrigger(ScheduleConfig scheduleConfig){

  64. return new Trigger() {

  65. @Override

  66. public Date nextExecutionTime(TriggerContext triggerContext) {

  67. CronTrigger trigger = new CronTrigger(scheduleConfig.getCron());

  68. Date nextExec = trigger.nextExecutionTime(triggerContext);

  69. return nextExec;

  70. }

  71. };

  72.  
  73. }

  74. }

启动类中添加@EnableScheduling

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现SpringBoot项目动态跑批定时任务,可以使用Spring自带的定时任务框架,结合数据库中存储的cron表达式来实现。 具体步骤如下: 1.在pom.xml文件中引入spring-boot-starter-quartz和spring-boot-starter-jdbc依赖。 2.在application.properties或application.yml中配置数据库连接信息。 3.创建一个Job类,实现Quartz的Job接口,并实现execute方法,该方法就是定时任务执行的业务逻辑。 4.创建一个JobDetail对象,表示一个具体的可执行的调度程序。 5.创建一个Trigger对象,表示触发Job执行的条件。 6.将JobDetail和Trigger注册到Scheduler中。 7.从数据库读取cron表达式,更新Trigger的cron表达式。 8.启动Scheduler,定时任务即可开始执行。 示例代码如下: 1.依赖配置: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> ``` 2.application.properties配置: ``` spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # Quartz spring.quartz.job-store-type=jdbc ``` 3.Job类: ``` @Component public class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 定时任务执行的业务逻辑 System.out.println("定时任务执行了"); } } ``` 4.创建JobDetail和Trigger对象: ``` @Autowired private MyJob myJob; @Autowired private Scheduler scheduler; public void startJob() throws SchedulerException { // 创建JobDetail对象 JobDetail jobDetail = JobBuilder.newJob(myJob.getClass()) .withIdentity("myJob", "group1") .build(); // 创建Trigger对象 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")) // 初始cron表达式 .build(); // 注册JobDetail和Trigger scheduler.scheduleJob(jobDetail, trigger); // 启动Scheduler scheduler.start(); } ``` 5.从数据库读取cron表达式,更新Trigger的cron表达式: ``` public void updateTrigger(String cron) throws SchedulerException { // 获取Trigger TriggerKey triggerKey = TriggerKey.triggerKey("myTrigger", "group1"); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 更新cron表达式 trigger = trigger.getTriggerBuilder() .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); // 重新注册Trigger scheduler.rescheduleJob(triggerKey, trigger); } ``` 6.调用startJob方法启动定时任务,调用updateTrigger方法动态更新cron表达式即可。 注意事项: 1.定时任务执行时间间隔不宜设置过短,避免对系统造成过大的负担。 2.更新cron表达式时需要先获取Trigger对象,然后重新构建Trigger对象并重新注册到Scheduler中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值