java 中Spring task定时任务的深入理解

在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutor和TaskScheduler这两个接口的方式为异步定时任务提供了一种抽象。这就意味着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表达式的格式如下:
{秒} {分} {时} {日期(具体哪天)} {月} {星期}
比如下面这个cron表达式:
// 表达的含义是:每半分钟触发一次任务 30 * * * * ?
spring提供了一个CronTrigger,通过传入一个Runnable任务和CronTrigger,就可以使用cron表达式去指定定时任务了,是不是非常方面。实际上,在工程实践上,cron表达式也是使用很多的。实际上,是执行了下面的代码:
scheduler.schedule(task, new CronTrigger("30 * * * * ?"));
TaskScheduler抽象的好处是让需要执行定时任务的代码不需要指定特定的定时框架(比如Timer和Quartz)。TaskScheduler的更简单的实现是ThreadPoolTaskScheduler,它实际上代理一个jdk中的SchedulingTaskExecutor,并且也实现了TaskExecutor接口,所以需要经常执行定时任务的场景可以使用这个实现(Spring推荐)。我们再来看一下TaskExecutor和TaskScheduler的类继承关系:
通常而言,使用spring task实现定时任务有两种方式:注解和xml配置文件。这里使用xml配置文件的方式加以说明。
实战
创建Maven工程,pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rhwayfun</groupId>
<artifactId>sring-task-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
开发需要执行定时任务的方法:
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配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">
<!-- 配置注解扫描 -->
<context:component-scan base-package="com.rhwayfun.task"/>
<task:scheduler id="taskScheduler" pool-size="100" />
<task:scheduled-tasks scheduler="taskScheduler">
<!-- 每半分钟触发任务 -->
<task:scheduled ref="app" method="execute1" cron="30 * * * * ?"/>
<!-- 每小时的10分30秒触发任务 -->
<task:scheduled ref="app" method="execute2" cron="30 10 * * * ?"/>
<!-- 每天1点10分30秒触发任务 -->
<task:scheduled ref="app" method="execute3" cron="30 10 1 * * ?"/>
<!-- 每月20号的1点10分30秒触发任务 -->
<task:scheduled ref="app" method="execute4" cron="30 10 1 20 * ?"/>
<!-- 每年10月20号的1点10分30秒触发任务 -->
<task:scheduled ref="app" method="execute5" cron="30 10 1 20 10 ?"/>
<!-- 每15秒、30秒、45秒时触发任务 -->
<task:scheduled ref="app" method="execute6" cron="15,30,45 * * * * ?"/>
<!-- 15秒到45秒每隔1秒触发任务 -->
<task:scheduled ref="app" method="execute7" cron="15-45 * * * * ?"/>
<!-- 每分钟的每15秒时任务任务,每隔5秒触发一次 -->
<task:scheduled ref="app" method="execute8" cron="15/5 * * * * ?"/>
<!-- 每分钟的15到30秒之间开始触发,每隔5秒触发一次 -->
<task:scheduled ref="app" method="execute9" cron="15-30/5 * * * * ?"/>
<!-- 每小时的0分0秒开始触发,每隔3分钟触发一次 -->
<task:scheduled ref="app" method="execute10" cron="0 0/3 * * * ?"/>
<!-- 星期一到星期五的10点15分0秒触发任务 -->
<task:scheduled ref="app" method="execute11" cron="0 15 10 ? * MON-FRI"/>
</task:scheduled-tasks>
</beans>
编写测试代码:
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");
}
}
运行测试代码,控制台会定时输出每个定时任务的日志信息,说明测试通过。
小插曲
由于项目使用jdk 1.8进行开发,所以初始的时候每次pom文件发生修改,编译器的版本又变成了jdk 1.5,后面发现需要在pom文件中添加build便签那部分才能将默认的编译器进行修改。也算一个小收获了。
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Spring
# task
# java中Spring
# task定时使用方法
相关文章:
如何快速搭建支持数据库操作的智能建站平台?
建设网站制作价格,怎样建立自己的公司网站?
网站网页制作电话怎么打,怎样安装和使用钉钉软件免费打电话?
行程制作网站有哪些,第三方机票电子行程单怎么开?
如何在宝塔面板创建新站点?
网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?
宝塔建站教程:一键部署配置流程与SEO优化实战指南
开封网站制作公司,网络用语开封是什么意思?
如何在自有机房高效搭建专业网站?
如何在Windows服务器上快速搭建网站?
如何通过IIS搭建网站并配置访问权限?
网站建设设计制作营销公司南阳,如何策划设计和建设网站?
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
移民网站制作流程,怎么看加拿大移民官网?
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
如何配置IIS站点权限与局域网访问?
如何自定义建站之星网站的导航菜单样式?
如何在阿里云ECS服务器部署织梦CMS网站?
清除minerd进程的简单方法
如何选择服务器才能高效搭建专属网站?
,购物网站怎么盈利呢?
免费制作小说封面的网站有哪些,怎么接网站批量的封面单?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
建站主机是什么?如何选择适合的建站主机?
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
建站之星北京办公室:智能建站系统与小程序生成方案解析
营销式网站制作方案,销售哪个网站招聘效果最好?
建站OpenVZ教程与优化策略:配置指南与性能提升
建站主机服务器选购指南:轻量应用与VPS配置解析
为什么Go需要go mod文件_Go go mod文件作用说明
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
建站之星安装失败:服务器环境不兼容?
香港服务器选型指南:免备案配置与高效建站方案解析
桂林网站制作公司有哪些,桂林马拉松怎么报名?
小型网站制作HTML,*游戏网站怎么搭建?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
如何用搬瓦工VPS快速搭建个人网站?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
如何基于云服务器快速搭建个人网站?
如何在万网自助建站中设置域名及备案?
建站主机如何选?高性价比方案全解析
如何在Golang中使用replace替换模块_指定本地或远程路径
微信小程序 五星评分(包括半颗星评分)实例代码
如何在橙子建站上传落地页?操作指南详解
怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?
建站之星多图banner生成与模板自定义指南
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
,南京靠谱的征婚网站?
如何在阿里云服务器自主搭建网站?
如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法
*请认真填写需求信息,我们会在24小时内与您取得联系。