Spring task定时任务

深入浅出spring task定时任务

在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutorTaskScheduler这两个接口的方式为异步定时任务提供了一种抽象。这就意味着spring容许你使用其他的定时任务框架,当然spring自身也提供了一种定时任务的实现:spring task。spring task支持线程池,可以高效处理许多不同的定时任务。同时,spring还支持使用Java自带的Timer定时器和Quartz定时框架。限于篇幅,这里将只介绍spring task的使用。

其实,官方文档已经介绍地足够详细,只不过都是英文版,所以为了更好地理解并使用spring task,首先会对spring task的实现原理做一个简单的介绍,然后通过实际代码演示spring task是如何使用的。这里会涉及到一个很重要的知识点:cron表达式。

TaskExecutor和TaskScheduler

TaskExecutor是spring task的第一个抽象,它很自然让人联想到jdk中concurrent包下的Executor,实际上TaskExecutor就是为区别于Executor才引入的,而引入TaskExecutor的目的就是为定时任务的执行提供线程池的支持,那么,问题来了,为什么spring不直接使用jdk自带的Executor呢?TaskExecutor源码如下:

public interface TaskExecutor extends Executor {
    void execute(Runnable var1);
}

那么,答案很显然,TaskExecutor提供的线程池支持也是基于jdk自带的Executor的。用法于Executor没有什么不同。

TaskScheduler是spring task的第二个抽象,那么从字面的意义看,TaskScheduler就是为了提供定时任务的支持咯。TaskScheduler需要传入一个Runnable的任务做为参数,并指定需要周期执行的时间或者触发器,这样Runnable任务就可以周期性执行了。传入时间很好理解,有意思的是传入一个触发器(Trigger)的情况,因为这里需要使用cron表达式去触发一个定时任务,所以有必要先了解下cron表达式的使用。

在spring 4.x中已经不支持7个参数的cronin表达式了,要求必须是6个参数(具体哪个参数后面会说)。cron表达式的格式如下:

{秒} {分} {时} {日期(具体哪天)} {月} {星期}

Spring task定时任务_第1张图片

比如下面这个cron表达式:

// 表达的含义是:每半分钟触发一次任务
30 * * * * ?
spring提供了一个 CronTrigger,通过传入一个Runnable任务和CronTrigger,就可以使用cron表达式去指定定时任务了,是不是非常方面。实际上,在工程实践上,cron表达式也是使用很多的。实际上,是执行了下面的代码:

scheduler.schedule(task, new CronTrigger("30 * * * * ?"));
TaskScheduler抽象的好处是让需要执行定时任务的代码不需要指定特定的定时框架(比如Timer和Quartz)。TaskScheduler的更简单的实现是 ThreadPoolTaskScheduler,它实际上代理一个jdk中的 SchedulingTaskExecutor,并且也实现了TaskExecutor接口,所以需要经常执行定时任务的场景可以使用这个实现(Spring推荐)

通常而言,使用spring task实现定时任务有两种方式:注解和xml配置文件。这里使用xml配置文件的方式加以说明。

实战

创建Maven工程,pom.xml:



    4.0.0

    com.rhwayfun
    sring-task-demo
    1.0-SNAPSHOT

    
        
            org.springframework
            spring-context
            4.2.4.RELEASE
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.5.1
                
                    1.8
                    1.8
                
            
        
    

开发需要执行定时任务的方法:

package com.rhwayfun.task;

import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author ZhongCB
 * @date 2016年09月10日 14:30
 * @description
 */
@Component
public class App {

    public void execute1(){
        System.out.printf("Task: %s, Current time: %s\n", 1, LocalDateTime.now());
    }

    public void execute2(){
        System.out.printf("Task: %s, Current time: %s\n", 2, LocalDateTime.now());
    }

    public void execute3(){
        System.out.printf("Task: %s, Current time: %s\n", 3, LocalDateTime.now());
    }

    public void execute4(){
        System.out.printf("Task: %s, Current time: %s\n", 4, LocalDateTime.now());
    }

    public void execute5(){
        System.out.printf("Task: %s, Current time: %s\n", 5, LocalDateTime.now());
    }

    public void execute6(){
        System.out.printf("Task: %s, Current time: %s\n", 6, LocalDateTime.now());
    }

    public void execute7(){
        System.out.printf("Task: %s, Current time: %s\n", 7, LocalDateTime.now());
    }

    public void execute8(){
        System.out.printf("Task: %s, Current time: %s\n", 8, LocalDateTime.now());
    }

    public void execute9(){
        System.out.printf("Task: %s, Current time: %s\n", 9, LocalDateTime.now());
    }

    public void execute10(){
        System.out.printf("Task: %s, Current time: %s\n", 10, LocalDateTime.now());
    }

    public void execute11(){
        System.out.printf("Task: %s, Current time: %s\n", 11, LocalDateTime.now());
    }

}

spring配置文件如下:




    
    

    

    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    


编写 测试代码:

package com.rhwayfun.task;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author ZhongCB
 * @date 2016年09月10日 14:55
 * @description
 */
public class AppTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/app-context-task.xml");
    }
}

运行测试代码,控制台会定时输出每个定时任务的日志信息,说明测试通过。

你可能感兴趣的:(Spring,spring,task)