首页 > 其他分享 >spring - mvc - @Scheduled

spring - mvc - @Scheduled

时间:2024-03-07 21:45:27浏览次数:31  
标签:Scheduled spring System 任务 mvc Spring public 1000

@Scheduled

1.启用调度支持

为了在Spring中启用对调度任务和@Scheduled注释的支持,我们可以使用Java启用样式注释:

@Configuration
@EnableScheduling
public class SpringConfig {
    ...
}

相反,我们可以在 XML 中做同样的事情:

<task:annotation-driven>

2.按固定延迟安排任务

让我们首先将任务配置为在固定延迟后运行:

@Scheduled(fixedDelay = 1000)
public void scheduleFixedDelayTask() {
    System.out.println(
      "Fixed delay task - " + System.currentTimeMillis() / 1000);
}

在这种情况下,上一次执行结束和下一次执行开始之间的持续时间是固定的。该任务总是等待,直到前一个任务完成。
当必须在再次运行之前完成先前的执行时,应使用此选项。

3.以固定速率安排任务

现在让我们以固定的时间间隔执行任务:

@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTask() {
    System.out.println(
      "Fixed rate task - " + System.currentTimeMillis() / 1000);
}

当任务的每次执行都是独立的时,应使用此选项。
请注意,默认情况下计划任务不会并行运行。因此,即使我们使用fixedRate,在前一个任务完成之前也不会调用下一个任务。
如果我们想在计划任务中支持并行行为,我们需要添加@Async注解:

@EnableAsync
public class ScheduledFixedRateExample {
    @Async
    @Scheduled(fixedRate = 1000)
    public void scheduleFixedRateTaskAsync() throws InterruptedException {
        System.out.println(
          "Fixed rate task async - " + System.currentTimeMillis() / 1000);
        Thread.sleep(2000);
    }

}

现在,即使前一个任务尚未完成,该异步任务也会每秒调用一次。

4.固定速率与固定延迟

我们可以使用 Spring 的@Scheduled注解来运行计划任务,但是根据属性fixedDelay 和 fixedRate, 执行的性质会发生变化。
fixedDelay属性确保任务执行的完成时间和下一次任务执行的开始时间之间有 n 毫秒的延迟。
当我们需要确保始终只有一个任务实例运行时,此属性特别有用。对于依赖工作来说,这是相当有帮助的。
fixedRate属性每 n毫秒运行一次计划任务。它不检查该任务的任何先前执行情况。
当任务的所有执行都是独立的时,这非常有用。如果我们不希望超出内存和线程池的大小,fixedRate 应该会很方便。
尽管如此,如果传入的任务没有快速完成,它们最终可能会出现“内存不足异常”。

5.安排一个带有初始延迟的任务

接下来,让我们安排一个有延迟(以毫秒为单位)的任务:

@Scheduled(fixedDelay = 1000, initialDelay = 1000)
public void scheduleFixedRateWithInitialDelayTask() {
 
    long now = System.currentTimeMillis() / 1000;
    System.out.println(
      "Fixed rate task with one second initial delay - " + now);
}

请注意在此示例中我们如何同时使用fixedDelay和initialDelay。任务会在initialDelay值之后第一次执行,并且会按照fixedDelay继续执行。
当任务有需要完成的设置时,此选项很方便

6.使用 Cron 表达式安排任务

有时延迟和速率还不够,我们需要 cron 表达式的灵活性来控制任务的时间表:

@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
 
    long now = System.currentTimeMillis() / 1000;
    System.out.println(
      "schedule tasks using cron jobs - " + now);
}

请注意,在此示例中,我们计划在每月 15 日上午 10:15 执行一个任务。
默认情况下,Spring 将使用服务器的本地时区作为 cron 表达式。但是,我们可以使用 zone属性来更改该时区:

@Scheduled(cron = "0 15 10 15 * ?", zone = "Europe/Paris")

通过此配置,Spring 将安排带注释的方法在巴黎时间每月 15 日上午 10:15 运行。

7.参数化时间表

对这些时间表进行硬编码很简单,但我们通常需要能够控制时间表,而无需重新编译和重新部署整个应用程序。
我们将使用 Spring 表达式来外部化任务的配置,并将它们存储在属性文件中。

// 固定延迟任务
@Scheduled(fixedDelayString = "${fixedDelay.in.milliseconds}"):
// 固定速率任务:
@Scheduled(fixedRateString = "${fixedRate.in.milliseconds}")
// 基于cron表达式的任务:
@Scheduled(cron = "${cron.expression}")

8.使用 XML 配置计划任务

Spring还提供了配置计划任务的XML方式。以下是用于设置这些的 XML 配置:

<!-- Configure the scheduler -->
<task:scheduler id="myScheduler" pool-size="10" />

<!-- Configure parameters -->
<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="beanA" method="methodA" 
      fixed-delay="5000" initial-delay="1000" />
    <task:scheduled ref="beanB" method="methodB" 
      fixed-rate="5000" />
    <task:scheduled ref="beanC" method="methodC" 
      cron="*/5 * * * * MON-FRI" />
</task:scheduled-tasks>

9.在运行时动态设置延迟或速率

通常, @Scheduled注解的所有属性仅在 Spring 上下文启动时解析和初始化一次。
因此,当我们在 Spring 中使用@Scheduled注解时,不可能在运行时更改fixedDelay或fixedRate值。
不过,有一个解决方法。使用Spring的SchedulingConfigurer提供了一种更加可定制的方式,使我们有机会动态设置延迟或速率。
让我们创建一个 Spring 配置DynamicSchedulingConfig并实现SchedulingConfigurer接口:

@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {

    @Autowired
    private TickService tickService;

    @Bean
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
          new Runnable() {
              @Override
              public void run() {
                  tickService.tick();
              }
          },
          new Trigger() {
              @Override
              public Date nextExecutionTime(TriggerContext context) {
                  Optional<Date> lastCompletionTime =
                    Optional.ofNullable(context.lastCompletionTime());
                  Instant nextExecutionTime =
                    lastCompletionTime.orElseGet(Date::new).toInstant()
                      .plusMillis(tickService.getDelay());
                  return Date.from(nextExecutionTime);
              }
          }
        );
    }
}

正如我们注意到的,借助ScheduledTaskRegistrar#addTriggerTask方法,我们可以添加一个Runnable任务和一个Trigger实现,以在每次执行结束后重新计算nextExecutionTime 。
此外,我们使用@EnableScheduling注释DynamicSchedulingConfig以使调度工作。
因此,我们安排TickService#tick方法在每次延迟后运行它,该延迟是在运行时由getDelay方法动态确定的。

10.并行运行任务

默认情况下,Spring 使用本地单线程调度程序来运行任务。因此,即使我们有多个@Scheduled方法,它们每个都需要等待线程完成执行上一个任务。
如果我们的任务真正独立,那么并行运行它们会更方便。为此,我们需要提供一个更适合我们需求的TaskScheduler :

@Bean
public TaskScheduler  taskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    return threadPoolTaskScheduler;
}

在上面的示例中,我们将TaskScheduler配置为池大小为 5,但请记住,实际配置应根据具体需求进行微调。

11.使用 Spring Boot

如果我们使用 Spring Boot,我们可以使用更方便的方法来增加调度程序池的大小。
设置spring.task.scheduling.pool.size属性就足够了:
spring.task.scheduling.pool.size=5

标签:Scheduled,spring,System,任务,mvc,Spring,public,1000
From: https://www.cnblogs.com/dkpp/p/18059842

相关文章

  • spring - springmvc - @EnableCaching
    @EnableCaching@EnableCaching注释在应用程序中启用注释驱动的缓存管理功能,并允许我们在应用程序中使用@Cacheable和@CacheEvict注释。具有类似功能的XML等效项是cache:*命名空间:@Configuration@EnableCachingpublicclassCacheConfig{@BeanpublicCacheMana......
  • SpringBoot 支付宝付款接口类、支付异步回调函数模板
    1.付款接口类1.1.引入Maven依赖<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.38.221.ALL</version></dependency>1.2.将下面代码保存为AlipayTemplate.java@Config......
  • SpringBoot-重要注解(1)
    ConfigurationProperties注解https://blog.csdn.net/skh2015java/article/details/120141409@Import、@ImportAutoConfigurationhttps://www.cnblogs.com/imyjy/p/16092825.html当我们需要在一个配置类中导入另一个Configuration配置类时,可以使用@Import、@ImportAuto......
  • Spring框架Bean对象的五个作用域
    ​ 一、前言:Bean对象简介在Spring项目中,那些由Spring IoC容器所管理的对象,称为bean。简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。 而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。上一段描述......
  • spring - mvc
    springmvc1.@Autowired@ComponentpublicclassFooService{@AutowiredprivateFooFormatterfooFormatter;}2.通过@Qualifier自动装配例如,让我们看看如何使用@Qualifier注释来指示所需的bean。首先,我们将定义2个Formatter类型的bean:@Component("fooFo......
  • SpringBoot3+Consul配置,启动后,居然不读bootstrap.yml的配置文件,直接连本地localhost:8
    问题描述如题。bootstrap.yml的配置文件: consul控制台打印的日志: 解决方案:booststrap.yml的配置文件缩进搞错了,所以压根就没有读到配置。正确的缩进:  ......
  • spring-webClient-响应式http客户端
    1.WebClient简介WebClient是SpringWebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。WebFlux对标SpringMvc,WebClient相当于RestTemplate,同时也是Spring官方的Http请求工具。2.传统阻塞IO模型VS响应式IO模型传统阻塞IO模型RestTem......
  • spring-restTemplate-网络请求
    1,引言  现如今的IT项目,由服务端向外发起网络请求的场景,基本上处处可见!传统情况下,在服务端代码里访问http服务时,一般会使用JDK的HttpURLConnection或者Apache的HttpClient,不过这种方法使用起来太过繁琐,而且api使用起来非常的复杂,还得操心资源回收。  RestTempl......
  • Spring-@Bean-注解
    1.作用用于将对象存入spring的ioc容器中。@controller、@Service、@Component、@Configuration、@Repository等几个注解是一样的,都是负责将对象存入容器当中,而@Bean是用在方法上,将当前方法的返回值对象放到容器当中。2.使用@Bean一般出现在方法上面,也可用于自定义......
  • 若依集成CIM(即时推送系统)实现将服务端修改为SpringBoot+Vue前后端分离版(文末见代码
    ​ 场景若依前后端分离版本地搭建开发环境并运行项目的教程:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108465662 CIMGitee地址:https://gitee.com/farsunset/cimCIM项目是基于mina或者netty框架下的推送系统,我们平常使用第三方的推送SDK,如极光推送,百度......