spring 计划任务

您是否需要每天像闹钟一样在同一时间运行某个流程? 然后,Spring的预定任务适合您。 允许您使用@Scheduled注释方法,以使其在指定的时间或内部间隔运行。 在本文中,我们将研究建立一个可以使用计划任务的项目,以及如何使用不同的方法来定义它们的执行时间。

我将在本文中使用Spring Boot,以使依赖关系变得简洁而又简单,这是因为调度可用于spring-boot-starter依赖关系,该依赖关系几乎以某种方式包含在每个Spring Boot项目中。 这使您可以使用任何其他启动程序依赖项,因为它们会引入spring-boot-starter及其所有关系。 如果要包括确切的依赖项本身,请使用spring-context

您可以使用spring-boot-starter

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.0.0.RC1</version>
</dependency>

或直接使用spring-context

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.3.RELEASE</version>
</dependency>

创建计划任务非常简单。 将@Scheduled批注添加到希望自动运行的任何方法中,并将@EnableScheduling包含在配置文件中。

因此,例如,您可能会遇到类似以下的内容。

@Component
public class EventCreator {private static final Logger LOG = LoggerFactory.getLogger(EventCreator.class);private final EventRepository eventRepository;public EventCreator(final EventRepository eventRepository) {this.eventRepository = eventRepository;}@Scheduled(fixedRate = 1000)public void create() {final LocalDateTime start = LocalDateTime.now();eventRepository.save(new Event(new EventKey("An event type", start, UUID.randomUUID()), Math.random() * 1000));LOG.debug("Event created!");}
}

这里有很多代码对于运行计划任务并不重要。 正如我在一分钟前说过的,我们需要在方法上使用@Scheduled ,它将自动开始运行。 因此,在上面的示例中, create方法将每隔1000毫秒(1秒)开始运行,如注释的fixedRate属性所示。 如果我们想更改其运行频率,则可以增加或减少fixedRate时间,或者可以考虑使用可用的不同调度方法。

因此,您可能想知道其他方法是正确的吗? 好了,它们就在这里(我还将在此处包括fixedRate )。

  • fixedRatefixedRate调用之间以固定的毫秒周期执行该方法。
  • fixedRateString一样的fixedRate ,但有一个字符串值来代替。
  • fixedDelay在一次调用结束与下一次调用之间以固定的毫秒fixedDelay执行该方法。
  • fixedDelayString一样fixedDelay但一个字符串值来代替。
  • cron使用类似cron的表达式来确定何时执行该方法(我们将在稍后对此进行更深入的研究)。

@Scheduled批注还有一些其他实用程序属性。

  • zone指示将解析cron表达式的时区,如果不包括时区,它将使用服务器的默认时区。 因此,如果您需要它在特定时区运行,例如香港,则可以使用zone = "GMT+8:00"
  • initialDelay延迟第一次执行计划任务的毫秒数,需要使用固定速率或固定延迟属性之一。
  • initialDelayString同为initialDelay但一个字符串值来代替。

以下是一些使用固定速率和延迟的示例。

@Scheduled(fixedRate = 1000)

与之前相同,每1秒运行一次。

@Scheduled(fixedRateString = "1000")

同上。

@Scheduled(fixedDelay = 1000)

在上一次调用完成后运行1秒。

@Scheduled(fixedRate = 1000, initialDelay = 5000)

每秒运行一次,但要等待5秒钟才能首次执行。

现在来看一下cron属性,它可以对任务的调度进行更多控制,让我们定义任务运行的秒数,分钟数和小时数,还可以进一步定义任务的运行年限。

以下是构建cron表达式的组件的细分。

  • Seconds值可以为0-59或特殊字符, - * /
  • Minutes值可以为0-59或特殊字符, - * /
  • Hours值可以为0-59或特殊字符, - * /
  • Day of month值可以为1-31或特殊字符, - * ? / LWC , - * ? / LWC
  • Month值可以为1-12JAN-DEC或特殊字符, - * /
  • Day of week值可以是1-7SUN-SAT或特殊字符, - * ? / LC # , - * ? / LC #
  • Year可以为空,值可以为1970-2099或特殊字符, - * /

为了更加清晰起见,我将细目分类组合成一个由字段标签组成的表达式。

@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")

请不要在表达式中包括花括号(我用它们来使表达式更清晰)。

在我们继续之前,我们需要了解特殊字符的含义。

  • *表示所有值,因此,如果在第二个字段中使用,则表示每秒或在天字段中使用,表示每天运行。
  • ? 表示没有特定的值,并且可以在“月的天”或“星期几”字段中使用,其中使用一个会使另一个无效。 如果我们指定在一个月的15日触发,则一个? 将在“ Day of week字段中使用。
  • -表示值的范围(例如,小时数字段中的1-3表示小时数1、2和3)。
  • ,代表附加价值,例如周一,周三,SUN在本周,说明此一天,在周一,周三和周日。
  • /代表增量,例如,秒字段中的0/15从0(0、15、30和45)开始每15秒触发一次。
  • L代表一周或一个月的最后一天。 请记住,在这种情况下,星期六是一周的结束,因此在星期几字段中使用L将在星期六触发。 可以与月日字段中的数字结合使用,例如6L代表月的最后一个星期五,或者L-3这样的表达式表示月的最后一天。 如果我们在“星期几”字段中指定一个值,则必须使用? 在“日”字段中,反之亦然。
  • W表示每月的最接近的工作日。 例如,如果15W是工作日,则在每月的第15天触发,否则它将在最近的工作日运行。 该值不能用于日期值列表中。
  • #指定任务应该在星期几和星期几触发。 例如, 5#2表示该月的第二个星期四。 如果您指定的日期和星期溢出到下个月,则不会触发。

在这里可以找到有用的资源,其中的解释稍长一些,这有助于我撰写本文。

让我们来看几个例子。

@Scheduled(cron = "0 0 12 * * ?")

每天晚上12点开火。

@Scheduled(cron = "0 15 10 * * ? 2005")

2005年每天早上10:15触发。

@Scheduled(cron = "0/20 * * * * ?")

每20秒触发一次。

有关更多示例,请参见我前面提到的链接, 此处再次显示。 幸运的是,如果您在编写一个简单的cron表达式时遇到麻烦,那么您应该可以在Google中找到所需的方案,因为有人可能已经在Stack Overflow上问了相同的问题。

要将上述内容与一个小的代码示例绑定在一起,请参见下面的代码。

@Component
public class AverageMonitor {private static final Logger LOG = LoggerFactory.getLogger(AverageMonitor.class);private final EventRepository eventRepository;private final AverageRepository averageRepository;public AverageMonitor(final EventRepository eventRepository, final AverageRepository averageRepository) {this.eventRepository = eventRepository;this.averageRepository = averageRepository;}@Scheduled(cron = "0/20 * * * * ?")public void publish() {final double average =eventRepository.getAverageValueGreaterThanStartTime("An event type", LocalDateTime.now().minusSeconds(20));averageRepository.save(new Average(new AverageKey("An event type", LocalDateTime.now()), average));LOG.info("Average value is {}", average);}
}

在这里,我们有一个类,每20秒查询Cassandra以获取同一时间段内事件的平均值。 同样,这里的大多数代码都是@Scheduled批注中的噪音,但是在野外看到它可能会有所帮助。 此外,如果您一直保持观察,对于这种每20秒运行一次的用例,在这里我们使用频率如此之高,因此,使用fixedRate以及可能使用fixedDelay属性代替cron更为合适。

@Scheduled(fixedRate = 20000)

是上面使用的cron表达式的fixedRate等效项。

我前面提到的最终要求是将@EnableScheduling批注添加到配置类。

@SpringBootApplication
@EnableScheduling
public class Application {public static void main(final String args[]) {SpringApplication.run(Application.class);}
}

作为一个很小的Spring Boot应用程序,我已经将@EnableScheduling批注附加到主@SpringBootApplication类。

总而言之,我们可以安排任务使用@Scheduled注释以及执行之间的毫秒级速率或cron表达式来触发,以实现无法用前者表达的更精确的时序。 对于需要经常运行的任务,使用fixedRatefixedDelay属性就足够了,但是一旦执行之间的时间变大,则很难快速确定所定义的时间。 发生这种情况时,应使用cron属性以更好地了解计划的时间。

这篇文章中使用的少量代码可以在我的GitHub上找到 。

如果您发现这篇文章很有帮助,并希望在我撰写新教程时保持最新,请在Twitter上@LankyDanDev关注我。

翻译自: https://www.javacodegeeks.com/2018/02/running-time-springs-scheduled-tasks.html

spring 计划任务

spring 计划任务_与Spring的计划任务一起按时运行相关推荐

  1. spring mysql 注解_【Spring】SpringMVC之基于注解的实现SpringMVC+MySQL

    目录结构: contents structure [-] SpringMVC是什么 MVC的全称是Model View Controller,通过实现MVC框架可以很好的数据.视图.业务逻辑进行分离. ...

  2. spring生命周期_理解Spring应用上下文生命周期

    Spring应用上下文启动准备阶段 `BeanFactory`创建阶段 `BeanFactory`准备阶段 `BeanFactory`后置处理阶段 `AnnotationConfigServletWe ...

  3. spring boot测试_测试Spring Boot有条件的合理方式

    spring boot测试 如果您或多或少有经验的Spring Boot用户,那么很幸运,在某些时候您可能需要遇到必须有条件地注入特定bean或配置的情况 . 它的机制是很好理解的 ,但有时这样的测试 ...

  4. spring 事务 会话_测试Spring的“会话”范围

    spring 事务 会话 在基于Spring的Web应用程序中,bean的作用域可以是用户"会话". 从本质上讲,这意味着对会话范围Bean的状态更改仅在用户会话范围内可见. 本条 ...

  5. java spring 条件注解_【Spring】Spring高级话题-条件注解-@Condition

    进行本示例的演示,需要先配置好Maven和Spring哦. 见: [Spring]基于IntelliJ IDEA搭建Maven 分析 通过profile,我们可以获得不同的profile,我们可以获得 ...

  6. spring 工作流引擎_带Spring的简单工作流引擎

    spring 工作流引擎 几个月前,在处理一个公司项目时,我们需要开发REST服务,该服务用于根据客户端应用程序发送的数据发送电子邮件. 在开发此服务期间,我们决定创建简单的工作流引擎,该引擎将为发送 ...

  7. 怎样参与火箭计划币_从目的到计划不是火箭科学

    怎样参与火箭计划币 Purpose, mission, principles, vision, strategy, plan. The world is full of fuzzy words, ov ...

  8. java+spring+mysql配置_用spring的beans配置mysql数据库

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www. ...

  9. spring 扫描所有_从Spring的几个阶段理解其工作过程

    首发于博客园,https://www.cnblogs.com/ibigboy/p/11150237.html Spring框架非常强大,想要彻底弄懂Spring是非常困难的. 为了便于初学者了解Spr ...

最新文章

  1. 清华唐杰教授:人工智能的下一个十年,认知推理是重点(附PPT下载)
  2. NASA发现超级地球,真的适宜居住?
  3. 基于正态分布的图片高斯模糊算法
  4. IIR+双向滤波实现系统零相位相移_MATLAB仿真
  5. ubuntu14.04安装完ros后常用的其他安装
  6. java8 默认方法_Java 8的默认方法:可以做什么和不能做什么?
  7. Docker中级篇|深入探究Docker
  8. SpringCloud 使用Zuul构建微服务网关
  9. 高性能计算(HPC)的前景、如何学习HPC
  10. 索然无味的正则表达式
  11. redhat5.4上安装oracle9i
  12. 分析与设计:员工管理系统
  13. MySQL子查询(嵌套查询)-----详细
  14. Android安装同应用不同版本,android一个应用如何在一个手机上装多个不同版本的方法...
  15. 因设计或者设施缺陷导致道路交通事故赔偿问题的法律依据
  16. 微信破解WiFi密码如何操作?一招帮你查看密码!
  17. 决策树CART、ID3、C4.5原理梳理
  18. 你应该知道的Android签名知识
  19. Random()类生成随机数详解
  20. Fedora-14源配置

热门文章

  1. [费用流专题]Going Home,Minimum Cost,工作安排
  2. P6466-分散层叠算法(Fractional Cascading)【模板】
  3. P5048-[Ynoi2019 模拟赛]Yuno loves sqrt technology III【分块】
  4. P4593-[TJOI2018]教科书般的亵渎【拉格朗日差值】
  5. Spark入门(十七)之单表关联
  6. MySQL - InnoDB特性 - Buffer Pool漫谈
  7. jstl中添加自定义的函数
  8. C++描述杭电OJ 2009.求数列的和 ||
  9. 一个朋友的一天,太酸了!
  10. 属性编辑器未在PropertyEditorManager中注册?