參考:
https://www.cnblogs.com/qlqwjy/p/9960706.html
https://blog.csdn.net/debugbugbg/article/details/81091715
https://blog.csdn.net/weixin_43777983/article/details/99685666
https://www.cnblogs.com/throwable/p/12616945.html -todo
SpringTask定時任務的使用
實現定時任務簡單的有四種方式:Timer\ScheduledThreadPool線程池\quartz(常用),還有另一種就是springtask。
都說springtask上手簡單,於是簡單的研究一下springtask的使用,並且運用到自己的項目中。其也有兩種配置方式,第一種是基於xml配置,第二種是基於注解。
SprngTask沒有專門的包,其核心類位於spring-context包中。所以引入spring的核心包此功能即可使用。
在實際的項目中,我們經常將job作為action層,在job中注入service去操作底層的dao,或者定時的向其他系統拉取數據,再或者向其他系統推送數據。
1.基於xml配置的簡單的使用
測試類:(每五秒鍾打印一次日志)
package cn.xm.exam.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public class FirstTestJob { private static final Logger log = LoggerFactory.getLogger(FirstTestJob.class); private static int count; public void cron() { log.info("spring task execute times {}", count++); } }
xml配置:(非常類似於quartz的cron表達式和linux定時的cron表達式)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <context:component-scan base-package="cn.xm.exam.job"></context:component-scan> <task:scheduled-tasks> <task:scheduled ref="firstTestJob" method="cron" cron="0/5 * * * * ?" /> </task:scheduled-tasks> </beans>
重點是引入task的schema:
xmlns:task="http://www.springframework.org/schema/task" http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
結果:
...
2018-11-14 22:35:00 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 59 2018-11-14 22:35:05 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 60 2018-11-14 22:35:10 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 61 2018-11-14 22:35:15 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 62 2018-11-14 22:35:20 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 63 2018-11-14 22:35:25 [cn.xm.exam.job.FirstTestJob]-[INFO] spring task execute times 64 ...
2.基於注解的使用
首先查看注解的源碼:
注解使用必須在xml中開啟注解任務,使注解生效:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <context:component-scan base-package="cn.xm.exam.job"></context:component-scan> <!-- 開啟注解任務 --> <task:annotation-driven /> </beans>
測試類:(每十秒鍾打印一次日志)
package cn.xm.exam.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class FirstAnnotationJob { private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class); private static int count; @Scheduled(cron = "0/10 * * * * ?") public void cron() { log.info("spring anno task execute times {}", count++); } }
結果:
2018-11-14 22:44:40 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 0 2018-11-14 22:44:50 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1 2018-11-14 22:45:00 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2 2018-11-14 22:45:10 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3
查看@Scheduled的源碼:(位於spring-context包內)
/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */ package org.springframework.scheduling.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Scheduled { /** * A cron-like expression, extending the usual UN*X definition to include * triggers on the second as well as minute, hour, day of month, month * and day of week. e.g. {@code "0 * * * * MON-FRI"} means once per minute on * weekdays (at the top of the minute - the 0th second). * @return an expression that can be parsed to a cron schedule * @see org.springframework.scheduling.support.CronSequenceGenerator */ String cron() default ""; /** * Execute the annotated method with a fixed period between the end * of the last invocation and the start of the next. * @return the delay in milliseconds */ long fixedDelay() default -1; /** * Execute the annotated method with a fixed period between invocations. * @return the period in milliseconds */ long fixedRate() default -1; /** * Number of milliseconds to delay before the first execution of a * {@link #fixedRate()} or {@link #fixedDelay()} task. * @return the initial delay in milliseconds * @since 3.2 */ long initialDelay() default 0; }
參數解釋:(其實源碼的注釋也寫的非常清楚了)
cron:cron表達式
fixedDelay:表示從上一個任務完成開始到下一個任務開始的間隔,單位是毫秒
fixedRate:從上一個任務開始到下一個任務開始的間隔,單位是毫秒。
initialDelay:任務第一次被調用前的延時,單位毫秒。
需要注意的是上面的前三個屬性只能保留一個,不能同時出現,最后一個延時操作可以與上面三個參數搭配。否則會報異常如下:
java.lang.IllegalArgumentException: Exactly one of the 'cron', 'fixedDelay', or 'fixedRate' attributes is required.
接下來我們測試上面的參數:
fixedDelay :方法中模擬處理用了2s
package cn.xm.exam.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class FirstAnnotationJob { private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class); private static int count; @Scheduled(fixedDelay = 10000) public void cron() { try { Thread.sleep(2000); } catch (InterruptedException e) { log.error("InterruptedException ", e); } log.info("spring anno task execute times {}", count++); } }
結果:(實際每兩次任務中間相差12s,也就是第一次任務結束10s后開啟下次任務)
2018-11-14 23:02:04 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1 2018-11-14 23:02:16 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2 2018-11-14 23:02:28 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3 2018-11-14 23:02:40 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 4
fixedRate測試:
package cn.xm.exam.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class FirstAnnotationJob { private static final Logger log = LoggerFactory.getLogger(FirstAnnotationJob.class); private static int count; @Scheduled(fixedRate = 10000) public void cron() { try { Thread.sleep(2000); } catch (InterruptedException e) { log.error("InterruptedException ", e); } log.info("spring anno task execute times {}", count++); } }
結果:(每兩次任務相差10s,也就是本次任務開始之后10s后就開啟下次任務,不管中間處理花費多長時間)
2018-11-14 23:04:47 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 1 2018-11-14 23:04:57 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 2 2018-11-14 23:05:07 [cn.xm.exam.job.FirstAnnotationJob]-[INFO] spring anno task execute times 3
至此完成了springtask的測試,確實比quartz簡便的多,使用也簡單。
附一個在線cron表達式生成器:http://cron.qqe2.com/
SpringTask的入門使用
一、Spring Task簡介
1.定時任務
3.三種完成方法
1.java自帶的API java.util.Timer類 java.util.TimerTask類
2.Quartz框架 開源 功能強大 使用起來稍顯復雜
3.Spring 3.0以后自帶了task 調度工具,比Quartz更加的簡單方便
二、開發環境准備
1.創建一個JavaWeb項目
2.引入jar包
3.基本的配置
三、如何使用
1.純xml配置的方式
a.簡單定時任務
實現業務功能+配置定時間規則
b.復雜定時任務
cron表達式
2.全注解的方式
a.在業務方法上提供注解 @Service @Scheduled(參數相同)
b.開啟注解支持
@Scheduled所支持的參數:
1. cron:cron表達式,指定任務在特定時間執行;
2. fixedDelay:表示上一次任務執行完成后多久再次執行,參數類型為long,單位ms;
3. fixedDelayString:與fixedDelay含義一樣,只是參數類型變為String;
4. fixedRate:表示按一定的頻率執行任務,參數類型為long,單位ms;
5. fixedRateString: 與fixedRate的含義一樣,只是將參數類型變為String;
6. initialDelay:表示延遲多久再第一次執行任務,參數類型為long,單位ms;
7. initialDelayString:與initialDelay的含義一樣,只是將參數類型變為String;
8. zone:時區,默認為當前時區,一般沒有用到。
springboot使用:
啟動類:
testtask2
SpringTask 默認是單線程的 上面的兩個定時任務使用的都是同一個線程;在實際開發中,不希望所有的任務都運行在一個線程中,想要改成多線程,給SpringTask提供一個多線程的TaskScheduler,Spring已經有默認實現
結果:
Spring Task原理及使用
參考文章:
https://blog.csdn.net/u011116672/article/details/52517247
https://blog.csdn.net/lucky_ly/article/details/78726307
Spring Task的作用是處理定時任務。Spring中為定時任務提供TaskExecutor,TaskScheduler兩個接口。
TaskExecutor繼承了jdk的Executor:
public interface TaskExecutor extends Executor {
void execute(Runnable var1);
}
這意味着他就是一個execute。
TaskScheduler提供定時器支持,即定時滴執行任務:
scheduler.schedule(task, new CronTrigger("30 * * * * ?"));
通過上面的方法,傳入一個Rannable任務,Trigger觸發器,就可以定時滴執行任務了,具體應用了cron表達式。
在spring 4.x中已經不支持7個參數的cronin表達式了,要求必須是6個參數(具體哪個參數后面會說)。cron表達式的格式如下:
{秒} {分} {時} {日期(具體哪天)} {月} {星期}
1
秒:必填項,允許的值范圍是0-59,支持的特殊符號包括
, - * /,,表示特定的某一秒才會觸發任務,-表示一段時間內會觸發任務,*表示每一秒都會觸發,/表示從哪一個時刻開始,每隔多長時間觸發一次任務。
分:必填項,允許的值范圍是0-59,支持的特殊符號和秒一樣,含義類推
時:必填項,允許的值范圍是0-23,支持的特殊符號和秒一樣,含義類推
日期:必填項,允許的值范圍是1-31,支持的特殊符號相比秒多了?,表示與{星期}互斥,即意味着若明確指定{星期}觸發,則表示{日期}無意義,以免引起沖突和混亂。
月:必填項,允許的值范圍是1-12(JAN-DEC),支持的特殊符號與秒一樣,含義類推
星期:必填項,允許值范圍是1~7 (SUN-SAT),1代表星期天(一星期的第一天),以此類推,7代表星期六,支持的符號相比秒多了?,表達的含義是與{日期}互斥,即意味着若明確指定{日期}觸發,則表示{星期}無意義。
通常而言,可以使用xml配合注解開發,以及注解開發兩種。
具體做法為:
1.引入pom文件
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
2.添加定時執行的任務
<context:component-scan base-package="com.springTask"/>
<task:scheduled-tasks>
<task:scheduled ref="taskTest" method="execute" cron="0/1 * * * * ?"/>
</task:scheduled-tasks>
第二種方式,主要基於注解
package com.springTask;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.config.TaskExecutorFactoryBean;
import org.springframework.stereotype.Component;
@Component
public class TaskTest {
@Scheduled(cron="* * * * * ?")
public void execute(){
System.out.println("let's go on " + new SimpleDateFormat().format(new Date()).toString());
}
}
xml配置文件:
<task:annotation-driven/>
<context:component-scan base-package="com.zx.jeeTomatoSyS.*"/>
<task:scheduler id="scheduler" pool-size="100"/>
第三種方式,基於注解:
任務類上 @EnableScheduling 即可。
xml配置文件:
<task:annotation-driven/>
<context:component-scan base-package="com.zx.jeeTomatoSyS.*"/>