Java传统定时任务实现

项目中使用定时任务处理业务是很常见的需求,现整理了一下Java传统定时任务的几种实现

一.分类

从实现的技术上来分类,目前主要有三种技术(或者说有三种产品)

  • Java自带的java.util.Timer类

    这个类允许你调度一个java.util.TimerTask任务。
    使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。
    一般用的较少,这篇文章将不做详细介绍。
    
  • Quartz

    这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行
    配置起来稍显复杂,稍后会详细介绍。
    
  • Spring Task

    Spring3.0以后自带的task
    可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多,稍后会介绍。
    

从作业类的继承方式,可以分为两类

  • 作业类需要继承特定的作业类基类

    Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBean
    java.util.Timer中需要继承自java.util.TimerTask
    
  • 作业类是普通的java类,不需要继承任何基类

    个人推荐使用这种方式,因为这样所有的类都是普通类,不需要区别对待,保证程序的扩展性
    

按照作业触发时机,可以分为两类

  • 每隔指定时间则触发一次

    在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
    
  • 每到指定时间则触发一次

    在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean
    

注意⚠️:并非每种任务都可以使用这两种触发器,如:Java.util.TimerTask任务就只能使用第一种,Quartz和Spring Task都可以支持这两种触发条件。

二.使用

现详细介绍一下Quartz和Spring Task如何使用

使用Quartz

  • Quartz是OpenSymphony开源组织在Job scheduling领域的开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表
  • Quartz是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统
  • Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度

Quartz中的核心对象

Scheduler   -- 核心调度器
Job         -- 任务
JobDetail   -- 任务描述
Trigger     -- 触发器
  • scheduler是一个计划调度器容器,容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就班自动去执行。
  • JobDetail是一个可执行的工作,它本身可能是有状态的。
  • Trigger代表一个调度参数的配置,什么时候去调。
  • 当JobDetail和Trigger在scheduler容器上注册后,形成了装配好的作业(JobDetail和Trigger所组成的一对儿),就可以伴随容器启动而调度执行了。
  • scheduler是个容器,容器中有一个线程池,用来并行调度执行每个作业,这样可以提高容器效率。
对象之间的关系

对象之间的关系

Java中使用Quartz示例

1.项目中引入maven依赖

  
  
    org.quartz-scheduler
    quartz
    2.3.0
  

2.编写作业类
Java中可以使用两种实现方式

  • 作业类继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean(不推荐,就不写实现了)

  • 作业类不继承自特定的基类
    Spring能够支持这种方式,归功于两个类:

     org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean
    
     org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
    

    这两个类分别对应spring支持的两种实现任务调度的方式,即前文提到到java自带的timer task方式和Quartz方式。
    这里我只写MethodInvokingJobDetailFactoryBean的用法,使用该类的好处是,我们的任务类不再需要继承自任何类,而是普通的pojo,作业类代码如下:

    package com.chainfin.ssmdemo.tasks;
    
    public class QuartzJob {
        public void task1(){
          System.out.println("Hello Quartz");
        }
    }
    

3.配置作业类


    
        
    
    
    

4.配置触发器


    
    

5.配置调度工厂


    
        
            
        
    

运行效果如下:


Quartz定时任务执行结果.png

使用Spring Task

Spring Task是Spring3.0以后自主开发的定时任务工具,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种

第一种配置文件方式

1.编写任务类

  package com.chainfin.ssmdemo.tasks;

  import org.springframework.stereotype.Component;

  @Component
  public class SpringTaskJob {
      public void task1(){
          System.out.println("Hello Spring Task1 ......");
      }
  }

2.在spring配置文件中设置具体的任务

  
      
  

注意⚠️:需要在配置文件头部增加task的命名空间及描述,如果你的开发工具是IDEA,会自动提示你引入对应的命名空间及描述,引入即可
运行效果:


Spring Task配置文件定时任务.png
第二种:使用注解@Scheduled形式

也许我们不想每写一个任务类还要在xml文件中配置下,我们可以使用注解@Scheduled,我们看看源文件中该注解的定义:
Java代码 :

@Target({java.lang.annotation.ElementType.METHOD,     java.lang.annotation.ElementType.ANNOTATION_TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface Scheduled  {  
   public abstract String cron();    
   public abstract long fixedDelay(); 
   public abstract long fixedRate();  
}  

可以看出该注解有三个方法或者叫参数,分别表示的意思是:
1.cron:指定cron表达式
2.fixedDelay:官方文档解释:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。
3.fixedRate:官方文档解释:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。
1.编写任务类

package com.chainfin.ssmdemo.tasks;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class SpringTaskJob {
    public void task1() {
        System.out.println("Hello Spring Task1 ......");
    }

    @Scheduled(cron = "*/10 * * * * ?")
    public void task2() {
        System.out.println("Hello Spring Task2 ......");
    }
}

2.在Spring配置文件中打开注解驱动,使@Scheduled注解生效



运行效果:


Spring Task注解配置定时任务.png

你可能感兴趣的:(Java传统定时任务实现)