在Spring中使用JDK定时器实现调度任务

简介: 本文探讨Spring如何集成JDK的Timer定时器,实现计划执行任务。有时候,需要执行一些无用户交互的程序,就像在指定的时间间隔后台运行进程那样。比如,杀毒软件可以每隔2天就在后台运行一次。
本文探讨Spring如何集成JDK的Timer定时器,实现计划执行任务。

有时候,需要执行一些无用户交互的程序,就像在指定的时间间隔后台运行进程那样。比如,杀毒软件可以每隔2天就在后台运行一次。又比如某些程序每天都要连接一次服务器,查看有没有更新。

本文探讨Spring如何集成JDK的Timer定时器,实现计划执行任务。

一、Spring框架集成JDK的Timer

JDK的Timer任务对象提供了在指定时间执行任何任务的功能。我们来看下面的例子:

假设我们想写一个服务,此服务周期性的检查互联网连接,并用日志记录连接的状态。让我们假定此服务是全天候运行的,且每隔30秒执行一次。

所需要的JAR包如下:

log4j-1.2.13.jar
commons-logging-1.1.1.jar
spring-beans-3.2.4.RELEASE.jar
spring-context-3.2.4.RELEASE.jar
spring-context-support-3.2.4.RELEASE.jar
spring-core-3.2.4.RELEASE.jar
spring-expression-3.2.4.RELEASE.jar

二、写服务类

下面的类实现了互联网连接检查。

Listing 1: CheckInternetConnectionService.java
[java]   view plain copy print ?
  1. package com.chszs;  
  2. import java.net.URL;  
  3. import java.net.URLConnection;  
  4. import java.util.Date;  
  5.   
  6. public class CheckInternetConnectionService {  
  7.     public void checkConnection(){  
  8.         if(doCheck()){  
  9.             System.out.println(new Date() + "Internet connection available");  
  10.         }else{  
  11.             System.out.println(new Date() + "Internet connection not available");  
  12.         }  
  13.     }  
  14.       
  15.     private boolean doCheck(){  
  16.         URL urlObject = null;  
  17.         URLConnection urlConnection = null;  
  18.         try{  
  19.             urlObject = new URL("http://www.baidu.com");  
  20.             urlConnection = urlObject.openConnection();  
  21.             urlConnection.getContent();  
  22.             return true;  
  23.         }catch(Exception e){  
  24.             return false;  
  25.         }  
  26.     }  
  27. }  

上面的代码很简单,doCheck()方法检查互联网连接是否有效。

三、封装定时器任务服务

下面我们写一个服务,实现定时任务。代码如下:

Listing 2: CheckInternetConnectionWithTimerTask
[java]   view plain copy print ?
  1. package com.chszs;  
  2. import java.util.TimerTask;  
  3.   
  4. public class CheckInternetConnectionWithTimerTask extends TimerTask{  
  5.     private CheckInternetConnectionService service;  
  6.       
  7.     public CheckInternetConnectionService getService(){  
  8.         return service;  
  9.     }  
  10.       
  11.     public void setService(CheckInternetConnectionService service){  
  12.         this.service = service;  
  13.     }  
  14.       
  15.     @Override  
  16.     public void run() {  
  17.         service.checkConnection();  
  18.     }  
  19. }  

此类继承了java.util.TimerTask类。

重写了run()方法,可以执行任意操作。这里是调用互联网连接检查。

注意定时器任务依赖于连接服务对象。稍后,我们将看到怎样连线这两个对象。

四、配置

至今,我们还没有指定执行的时间间隔。Spring提供了这样的配置支持。下面我们来看看该如何配置:

Listing 3: timer.xml
[html]   view plain copy print ?
  1. xml version="1.0" encoding="UTF-8"?>  
  2. beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  7.     http://www.springframework.org/schema/context  
  8.     http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  9.       
  10.     bean id="connectionCheckService" class="com.chszs.CheckInternetConnectionService">  
  11.     bean>  
  12.     bean id="connectionCheckTimerTask" class="com.chszs.CheckInternetConnectionWithTimerTask">  
  13.         property name="service" ref="connectionCheckService" />  
  14.     bean>  
  15.     bean id="scheduledConnectionCheckTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">  
  16.         property name="delay" value="2000" />  
  17.         property name="period" value="30000" />  
  18.         property name="timerTask" ref="connectionCheckTimerTask" />  
  19.     bean>  
  20.     bean class="org.springframework.scheduling.timer.TimerFactoryBean">  
  21.         property name="scheduledTimerTasks">  
  22.             list>  
  23.                 ref bean="scheduledConnectionCheckTimerTask" />  
  24.             list>  
  25.         property>  
  26.     bean>  
  27. beans>  

以上配置文件的细节:

"connectionCheckService"这个Bean表示互联网连接服务。

"connectionCheckTimerTask"这个Bean定义了定时器任务。由于此定时器任务依赖于"connectionCheckService"这个Bean,故通过配置进行注入。

下面的代码是从Spring框架中声明定时器任务的调度对象:
[html]   view plain copy print ?
  1. bean id="scheduledConnectionCheckTimerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">  
  2.     property name="delay" value="2000" />  
  3.     property name="period" value="30000" />  
  4.     property name="timerTask" ref="connectionCheckTimerTask" />  
  5. bean>  

org.springframework.scheduling.timer.ScheduledTimerTask这个类提供了对定时任务调度执行的支持。

属性delay的单位是毫秒,它指定任务执行前需要延时多少时间。2000意味着延时2秒开始执行任务。

第二个属性period的单位也是毫秒,它表示任务每隔多少时间就重复执行一次。30000这个值表示每隔30秒执行一次。

最后一个属性是timerTask,它指定实际要执行的任务。

触发调度任务是通过TimerFactoryBean进行的。它可以指定待调度的任务对象列表,尽管这里只有1个待调度的任务对象。
[html]   view plain copy print ?
  1. bean class="org.springframework.scheduling.timer.TimerFactoryBean">  
  2.     property name="scheduledTimerTasks">  
  3.         list>  
  4.             ref bean="scheduledConnectionCheckTimerTask" />  
  5.         list>  
  6.     property>  
  7. bean>  

五、客户端

客户端程序会载入应用程序的上下文。一旦上下文被载入,服务对象、定时器任务对象、调度的定时器任务对象都会被载入并连线。下面我们继续介绍触发器Bean是如何触发定时器任务的执行,互联网连接在每隔30秒运行一次。

Listing 4: Client.java
[java]   view plain copy print ?
  1. package com.chszs;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class Client {  
  7.     public static void main(String[] args){  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext("timer.xml");  
  9.     }  
  10. }  

运行Client.java,可以看到每隔30秒定时器任务就调度执行一次。
执行结果如下:
[html]   view plain copy print ?
  1. Sun Aug 11 21:08:26 CST 2013Internet connection available  
  2. Sun Aug 11 21:08:56 CST 2013Internet connection available  
  3. Sun Aug 11 21:09:26 CST 2013Internet connection available  
  4. Sun Aug 11 21:09:56 CST 2013Internet connection available  

目录
相关文章
|
29天前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
|
1月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
2月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
14609 25
|
1月前
|
Dubbo Java 调度
揭秘!Spring Cloud Alibaba的超级力量——如何轻松驾驭分布式定时任务调度?
【8月更文挑战第20天】在现代微服务架构中,Spring Cloud Alibaba通过集成分布式定时任务调度功能解决了一致性和可靠性挑战。它利用TimerX实现任务的分布式编排与调度,并通过`@SchedulerLock`确保任务不被重复执行。示例代码展示了如何配置定时任务及其分布式锁,以实现每5秒仅由一个节点执行任务,适合构建高可用的微服务系统。
47 0
|
1月前
|
安全 Java 网络安全
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
|
2月前
|
SQL Java 调度
实时计算 Flink版产品使用问题之使用Spring Boot启动Flink处理任务时,使用Spring Boot的@Scheduled注解进行定时任务调度,出现内存占用过高,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3月前
|
前端开发 Java 应用服务中间件
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
|
2月前
|
Java 数据处理 数据库
Spring Boot中的批处理任务实现
Spring Boot中的批处理任务实现
|
3月前
|
监控 Java 调度
Spring Boot中的定时任务调度
Spring Boot中的定时任务调度
|
3月前
|
Java Spring
深入解析Spring源码,揭示JDK动态代理的工作原理。
深入解析Spring源码,揭示JDK动态代理的工作原理。
41 0