来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合因为最近有个项目 要做类似于定时去连接其他系统接口 不停的获取数据 这种情况下 如果有新加入的接口 要自动检测连接 我们在做一些监控数据 实时做一些操作的时候

大家好,欢迎来到IT知识分享网。

这里为什么要说定时任务呢?

因为最近有个项目,要做类似于定时去连接其他系统接口,不停的获取数据,这种情况下,

如果有新加入的接口,要自动检测连接,我们在做一些监控数据,实时做一些操作的时候

往往需要用到定时任务,那么使用的时候:

1.如何选择定时任务,如果项目需要多节点部署,那么一开始的时候,最好就不要用Timer,

Timer不支持分布式,多个节点部署,需要自己设计多节点保活机制,需要自己设计节点选举,多活等

考虑这些问题,而且Timer是周期执行的,你不能指定比如每天早上10点开始执行.

2.可以使用Quartz,这个本身支持分布式部署,可以保证多个节点同时只有一个节点在运行定时任务,

但需要注意,要求各个服务器节点的时间要保持同步.

1.Timer的使用不用说了,来看一下Scheduled

@Configuration @EnableScheduling @Slf4j public class SpringScheduleConfig { private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Scheduled(fixedRate = 1000 * 60L) public void runIntervalTask(){ log.info("Spring3.*之后的自带定时任务实现 ===> fixedRate表示按固定频率执行该任务---打印当前时间:{}",sdf.format(new Date())); } @Scheduled(cron = "47 * * * * ?") public void runCornExpTask(){ log.info("Spring3.*之后的自带定时任务实现 ===> cron表示按corn表达式执行该任务---打印当前时间:{}",sdf.format(new Date())); } }
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

可以看到schduled的使用非常简单,不多说了.

2.然后看Quartz

  • Scheduler,调度器。作用是,用来统一管理工作内容、工作计划周期。
  • JobDetail,作业实例。作用是,用来定义某项具体工作的工作内容。
  • Trigger,触发器。作用是,用来定义某项具体工作的执行频率。

这些抽象概念不是那么容易理解,我以“吃饭”来简单讲解一下它们的含义。

比如我给自己定了一个计划表:每天8点到8点半吃早饭,每天12点到12点半吃午饭。用Quartz的概念解释如下:

  • 这个计划表,就是调度器(Scheduler),调度器告诉我们什么时候该干什么。然后,早饭吃的是豆浆+油条,午饭吃的是米饭。
  • 早饭、午饭就是作业实例(JobDetail),作业实例是用来定义某项具体工作的工作内容。
  • 8点到8点半、12点到12点半就是两个触发器(Trigger),触发器关联某个作业实例,告诉该作业实例在什么时候进行作业。

首先实现一个简单的任务:

1.添加依赖:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

2.添加具体工作内容

@Slf4j public class SimpleQuartzTask extends QuartzJobBean{ / * 实现QuartzJobBean的executeInternal()方法,即可定义工作内容 */ @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("简单的单Quartz任务开始---"); try { Thread.sleep(4000L); } catch (InterruptedException e) { log.error("线程阻塞失败。",e); } log.info("简单的单Quartz任务结束---"); } }
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

3.配置定时规则

@Configuration public class SimpleQuartzConfig { @Bean public JobDetail simpleQuartzTaskDetail(){ return JobBuilder.newJob(SimpleQuartzTask.class).withIdentity("simpleQuartzTask").storeDurably().build(); } @Bean public Trigger simpleQuartzTaskTrigger(){ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("*/3 * * * * ?"); return TriggerBuilder.newTrigger().forJob(simpleQuartzTaskDetail()) .withIdentity("simpleQuartzTask") .withSchedule(scheduleBuilder) .build(); } }
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

可以看到也很简单在Spring2.0以后,这个Quartz 已经很好的集成了.

上面是单任务的实现,然后我们再来看一个多任务的:

1.也是导入依赖

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

2.定义一个任务接口,以后其他任务都可以实现这个接口

public interface QuartzScheduleTask { / * 该方法的实现,表示某个任务的具体工作内容 */ void exec(); }
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

3.在配置文件中yml或者properties文件中配置

# quartz定时任务相关的配置 quartz.scheduler-name=QUARTZ_SCHEDULER quartz.thread-count=10 quartz.thread-name-prefix=quartz_worker quartz.tasks=\ ReportTimeTask:*/10 * * * * ? *
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

4.然后写一下多任务的配置

@Configuration @ConfigurationProperties("quartz") @Getter @Setter public class QuartzScheduleConfig { private String schedulerName; private String threadCount; private String threadNamePrefix; private String tasks; private final ApplicationContext context; @Autowired public QuartzScheduleConfig(ApplicationContext context) { this.context = context; } @Bean public SchedulerFactoryBean schedulerFactoryBean() { Properties properties = new Properties(); properties.setProperty("org.quartz.threadPool.threadCount", threadCount); properties.setProperty("org.quartz.threadPool.threadNamePrefix", threadNamePrefix); SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setSchedulerName(schedulerName); factory.setQuartzProperties(properties); return factory; } @Bean public Scheduler scheduler() throws Exception { Scheduler scheduler = schedulerFactoryBean().getScheduler(); scheduler.scheduleJobs(createJobDetails(), true); return scheduler; } / * 创建JobDetail * 使用是Spring的MethodInvokingJobDetailFactoryBean来创建JobDetail * 使用Spring的ronTriggerFactoryBean来创建CronTrigger * * @return Map<JobDetail, Set<CronTrigger>> */ private Map<JobDetail, Set<? extends Trigger>> createJobDetails(){ Set<String> taskSet = StringUtils.commaDelimitedListToSet(tasks); Map<JobDetail, Set<? extends Trigger>> map = new HashMap<>(taskSet.size()); for (String task : taskSet) { String[] nameAndCron = task.split(":"); String name = StringUtils.uncapitalize(nameAndCron[0]); String cron = nameAndCron[1]; MethodInvokingJobDetailFactoryBean factoryBean = new MethodInvokingJobDetailFactoryBean(); factoryBean.setTargetObject(context.getBean(name)); factoryBean.setName(name); factoryBean.setTargetMethod(QuartzScheduleTask.class.getMethods()[0].getName()); factoryBean.afterPropertiesSet(); CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setCronExpression(cron); cronTriggerFactoryBean.setJobDetail(factoryBean.getObject()); cronTriggerFactoryBean.setName(name); cronTriggerFactoryBean.afterPropertiesSet(); Set<CronTrigger> cronTriggerSet = new HashSet<>(1); cronTriggerSet.add(cronTriggerFactoryBean.getObject()); map.put(factoryBean.getObject(), cronTriggerSet); } return map; } } 
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

5.然后再去实现任务就可以了

最后,进行某项具体任务中工作内容的实现 @Slf4j @Component public class ReportTimeTask implements QuartzScheduleTask{ private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override public void exec() { log.info("执行的Quartz指定的任务,现在的时间是:{}",sdf.format(new Date())); } }
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

6.这样多任务就实现了以后再实现其他任务的时候

  1. 实现QuartzScheduleTask的exec()方法,定义该定时任务的工作内容;
  2. 在配置文件中加上该定时任务的触发器,就像上面加入的,例子中的那个一样

然后再来看一下,定时中使用的表达式吧:

SpringBoot是将一个定时任务看做一个方法。上面配置的做法是: 首先,读取配置文件中quartz.tasks中定义的任务名称及该任务的触发器。 然后,通过ApplicationContext(应用上下文对象),根据任务名称获取到相应的任务对象实例。 再然后,通过Spring的MethodInvokingJobDetailFactoryBean注册JobDetail,该任务实例的第一个方法就是该任务的工作内容;通过Spring的CronTriggerFactoryBean注册CornTrigger,该任务实例在配置文件中的内容,就是该任务的触发器。 把该任务的工作内容和触发器放在Map中,通过schedule的scheduleJobs()方法将所有JobDetail和Trigger添加到调度器中。 这样SpringBoot就会帮我们管理调度器schedule实例,并自动按计划执行相应的定时任务。 这里还需要注明一点:配置了多任务后,之前的单任务会失效。因为自定义的调度器Schdule中,并没有加入该单任务对应的JobDetai和Trigger,所以该调度器不会管理该单任务。 corn表达式简介 不管是Spring自带的定时任务实现,还是SpringBoot整合Quartz的定时任务实现,其触发器都支持用corn表达式来表示。 corn表达式是一个字符串,有6或7个域,域之间是用空格进行间隔。 从左到右每个域表示的含义如下: 第几个域 英文释义 允许值 备注 一 Seconds 0~59 秒 二 Minutes 0~59 分 三 Hours 0~23 时 四 DayOfMonth 1-31 天 五 Month 1-12或月份简写 月 六 DayOfWeek 1-7或星期简写 星期,1表示SUN 七 Year 1970~2099 年 然后,某些域还支持部分特殊字符,特殊字符的含义如下: 特殊字符 含义及注意事项 * 任意值 ? 占位符,只能在第四域和第六域中使用 - 区间,表示区间内有效 / 固定间隔 , 枚举有效值的间隔符 L 表示该区间的最后一个有效值,只能在第四域和第六域中使用 W 表示离指定日期的最近的有效工作日,(周一-周五为工作日) 常用corn表达式例子含义说明: corn表示式 表达式含义 */10 * * * * ? * 每隔10秒执行一次 0 30 1 * * ? * 每天凌晨1点30分0秒开始执行 0 0 10,14,16 * * ? 每天10点、14点、16点执行一次 0 15 10 L * ? 每个月最后一天的10点15分执行一次 0 15 10 ? * 6L 2018-2020 2018年到2020年每个月最后一个星期五的10:15执行
来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

来定时任务Timer_Scheduled_Quartz_如何在SpringBoot中整合

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/178042.html

(0)
上一篇 2025-05-07 11:00
下一篇 2025-05-07 11:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信