Spring实现定时任务方法

113 阅读7分钟



从 技术上说实现定时任务常见的方法有三种

  • Java自带的java.util.Timer类
  • 使用Quartz调度器,这种方式需要第三方jar支持
  • Spring3.0以后自带的task定时器


第一种方式在这里就不多做说明了,因为timer类功能比较单一,在实际项目中运用也比较少

Quartz

Quartz的使用方式大致有三种,这三种方式的在这里都会和进行整合所以都会用到applicationContext.xml进行配置

  • 实现org.quartz.StatefulJob或org.quartz.Job接口
  • 继承org.springframework.scheduling.quartz.QuartzJobBean类
  • 普通类+xml配置文件


1.实现org.quartz.StatefulJob或org.quartz.Job接口
首先在applicationContext.xml配置定时任务tomcat加载的初始化类,加载时运行init方法



  • <!-- 实现定时任务接口启动类 -->




  • <bean id="StarJob" class="com.lovo.task.server.impl.StarJob" init-method="init"></bean>


  • 1
  • 2
  • 1
  • 2
  • 1
  • 2


初始化类代码



  • package
    com.lovo.task.server.impl;







  • import
    org.quartz.Scheduler;



  • import
    org.quartz.SchedulerException;



  • import
    org.quartz.SchedulerFactory;



  • import
    org.quartz.impl.StdSchedulerFactory;







  • public
    class StarJob {







  • public
    void
    init
    ()
    throws
    SchedulerException{



  • //TestImpl为定时任务的配置实现类




  • TestImpl impl=
    new
    TestImpl();



  • SchedulerFactory factory =
    new
    StdSchedulerFactory();



  • Scheduler scheduler = factory.getScheduler();



  • try
    {



  • //触发作业类及触发器方法




  • impl.startJob(scheduler);



  • }
    catch
    (Throwable e) {



  • // TODO Auto-generated catch block




  • e.printStackTrace();



  • }



  • //启动定时任务




  • scheduler.start();



  • }



  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26



作业及调度实现类



  • package
    com.lovo.task.server.impl;







  • import
    java.text.ParseException;







  • import
    org.quartz.CronTrigger;



  • import
    org.quartz.JobDetail;



  • import
    org.quartz.JobExecutionContext;



  • import
    org.quartz.JobExecutionException;



  • import
    org.quartz.Scheduler;



  • import
    org.quartz.SchedulerException;



  • import
    org.quartz.SchedulerFactory;



  • import
    org.quartz.StatefulJob;



  • import
    org.quartz.Trigger;



  • import
    org.quartz.TriggerUtils;



  • import
    org.quartz.impl.StdSchedulerFactory;







  • import
    com.lovo.task.server.ITest;







  • public
    class TestImpl implements StatefulJob,ITest {















  • @Override



  • public
    void
    execute
    (JobExecutionContext arg0)
    throws
    JobExecutionException {



  • // TODO Auto-generated method stub




  • test();



  • }







  • @Override



  • public
    void
    startJob
    (Scheduler scheduler)
    throws
    Throwable {



  • //配置作业类




  • JobDetail JobDetail=
    new
    JobDetail(
    "TestImpl"
    ,Scheduler.DEFAULT_GROUP, TestImpl.class);



  • //任意每分钟类从0开始55结束,每5秒执行一次




  • String rex=
    "0/5 * * * * ?"
    ;



  • //触发器,配置调度工厂




  • CronTrigger trigger=
    new
    CronTrigger(
    "testTrigger"
    ,
    "testGroup"
    , rex);



  • scheduler.scheduleJob(JobDetail, trigger);







  • //固定每10秒执行一次




  • // Trigger simplerTrigger = TriggerUtils.makeSecondlyTrigger(10);




  • // simplerTrigger.setName("SimpleTrigger");




  • // scheduler.scheduleJob(JobDetail, simplerTrigger);








  • }







  • public
    void
    test
    (){



  • System.out.println(
    "测试"
    );



  • }







  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51




2.继承org.springframework.scheduling.quartz.QuartzJobBean类
首先在xml中进行配置



  • <!-- 配置计时任务 -->




  • <!-- 配置作业bean -->




  • <bean id="TestTaskImpl" class="org.springframework.scheduling.quartz.JobDetailBean">



  • <!-- value为类路径 -->




  • <property name="jobClass" value="com.lovo.task.server.impl.TestTaskImpl"></property>



  • <!-- 此属性定义方法需注入的属性值,time为工厂调度后多久开始执行 -->




  • <property name="jobDataAsMap">



  • <map>



  • <entry key="timeout" value="0"></entry>



  • </map>



  • </property>



  • </bean>







  • <!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次,-->




  • <!-- 固定频率执行 -->




  • <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">



  • <property name="jobDetail" ref="TestTaskImpl"></property>



  • <!-- 实例化后多久开始执行 -->




  • <property name="startDelay" value="0"></property>



  • <!-- 间隔频率,单位毫秒 -->




  • <property name="repeatInterval" value="1000"></property>



  • </bean>



  • <!-- 固定时间 每天12:00运行一次-->




  • <!-- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">




  • <property name="jobDetail" ref="TestTaskImpl" />




  • <property name="cronExpression" value="0 0 12 * * ?" />




  • </bean> -->








  • <!-- 配置调度工厂 -->




  • <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">



  • <property name="triggers">



  • <list>



  • <ref bean="simpleTrigger" />



  • </list>



  • </property>



  • </bean>


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36




作业类代码



  • package
    com.lovo.task.server.impl;







  • import
    org.quartz.JobExecutionContext;



  • import
    org.quartz.JobExecutionException;



  • import
    org.springframework.scheduling.quartz.QuartzJobBean;







  • import
    com.lovo.task.server.TestTask;







  • public
    class TestTaskImpl extends QuartzJobBean implements TestTask{







  • //time为工厂调度后多久开始执行




  • private
    int
    timeout;



  • public
    static
    int
    INDEX;







  • public
    void
    setTime
    (
    int
    timeout) {



  • this
    .timeout = timeout;



  • }











  • @Override



  • protected
    void
    executeInternal
    (JobExecutionContext arg0)



  • throws
    JobExecutionException {



  • // TODO Auto-generated method stub




  • testTask();



  • }







  • @Override



  • public
    void
    testTask
    () {



  • // TODO Auto-generated method stub




  • INDEX++;



  • System.out.println(
    "执行计时任务第"
    +INDEX+
    "次"
    );







  • }







  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1


3.普通类+xml配置文件
首先定义个普通



  • package com.lovo.task.server;







  • public
    class
    TestTask02
    {







  • public
    void
    Task
    (){



  • System.
    out
    .println(
    "普通类实现定时任务"
    );



  • }







  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10


在xml中进行配置



  • <!-- 普通类实现定时任务 -->




  • <!-- 配置作业类 -->




  • <bean id="Task02" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">



  • <!-- targetObject指定任务类 -->




  • <property name="targetObject">



  • <bean class="com.lovo.task.server.TestTask02"></bean>



  • </property>



  • <!-- targetMethod指定运行的方法 -->




  • <property name="targetMethod" value="Task"></property>



  • <!-- 不并发调度 -->




  • <property name="concurrent" value="false"></property>



  • </bean>







  • <!-- 配置调度触发器 触发器有两种配置方式,一直是固定多少时间循环一次,一种是每天固定几点执行一次 -->




  • <bean id="simpleTrigger02" class="org.springframework.scheduling.quartz.SimpleTriggerBean">



  • <property name="jobDetail" ref="Task02"></property>



  • <!-- 实例化后多久开始执行 -->




  • <property name="startDelay" value="0"></property>



  • <!-- 间隔频率,单位毫秒 -->




  • <property name="repeatInterval" value="1000"></property>



  • </bean>



  • <!-- 固定时间 每天12:00运行一次-->




  • <!-- <bean id="cronTrigger02" class="org.springframework.scheduling.quartz.CronTriggerBean">




  • <property name="jobDetail" ref="Task02" />




  • <property name="cronExpression" value="0 0 12 * * ?" />




  • </bean> -->




  • <!-- 配置调度工厂 -->




  • <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">



  • <property name="triggers">



  • <list>



  • <ref bean="simpleTrigger02" />



  • </list>



  • </property>



  • </bean>


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1


Spring-Task

Spring自带的Task实现定时任务也有两种方式,一种是xml配置的方式,一种是使用注解@Scheduled,不管是那种方式,首先都需要在xml开头声明task

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1

配置定时器开关



  • <!-- 配置定时器开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->




  • <!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->




  • <task:scheduler id="Scheduler" pool-size="10"/>



  • <task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/>


  • 1
  • 2
  • 3
  • 4
  • 1

基于注解的任务类



  • package
    com.lovo.task.server;







  • import
    org.springframework.scheduling.annotation.Scheduled;



  • import
    org.springframework.stereotype.Component;







  • @Component



  • public
    class Task03 {







  • @Scheduled(cron=
    "0/3 * * * * ?"
    )



  • public
    void
    test
    (){



  • System.out.println(
    "task定时任务"
    );



  • }







  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

如果不习惯注解的,追求代码的简洁性,也可以在xml中配置task定时任务



  • <!-- 配置作业bean -->




  • <bean id="xmlTask" class="com.lovo.task.server.Task04"></bean>







  • <!-- 配置执行规则 method为作业方法-->




  • <task:scheduled-tasks>



  • <task:scheduled ref="xmlTask" method="test" cron="0/2 * * * * ?"/>



  • </task:scheduled-tasks>







  • <!-- 配置定时器注解开关 里面可以配置很多参数,这里只是简单的打开task,并支持@Scheduled -->




  • <task:scheduler id="Scheduler" pool-size="10"/>



  • <task:annotation-driven scheduler="Scheduler" proxy-target-class="true"/>


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1

定时任务



  • package com.lovo.task.server;







  • public
    class
    Task04
    {







  • public
    void
    test
    (){



  • System.
    out
    .println(
    "xml中配置Task"
    );



  • }







  • }


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1

参考来源:

cronExpression语法
字段 允许值 允许的特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可选) 留空, 1970-2099 , - * /
- 区间
* 通配符
? 你不想设置那个字段
下面只例出几个式子

CRON表达式 含义
“0 0 12 * * ?” 每天中午十二点触发
“0 15 10 ? * *” 每天早上10:15触发
“0 15 10 * * ?” 每天早上10:15触发
“0 15 10 * * ? *” 每天早上10:15触发
“0 15 10 * * ? 2005” 2005年的每天早上10:15触发
“0 * 14 * * ?” 每天从下午2点开始到2点59分每分钟一次触发
“0 0/5 14 * * ?” 每天从下午2点开始到2:55分结束每5分钟一次触发
“0 0/5 14,18 * * ?” 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发
“0 0-5 14 * * ?” 每天14:00至14:05每分钟一次触发
“0 10,44 14 ? 3 WED” 三月的每周三的14:10和14:44触发
“0 15 10 ? * MON-FRI” 每个周一、周二、周三、周四、周五的10:15触发

更多技术资讯可关注:gzitcast