`
lengchaotian
  • 浏览: 278488 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

java 定时器几种方式

阅读更多

quartz

spring

spring-task

定时任务

注解

 

Spring定时任务的几种实现

 

近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,所以我都将结合

 

spring框架来介绍。

一.分类

 

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

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

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

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

 

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

作业类需要继承自特定的作业类基类,如Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBeanjava.util.Timer中需要继承自java.util.TimerTask

作业类即普通的java类,不需要继承自任何基类。

 

:个人推荐使用第二种方式,因为这样所以的类都是普通类,不需要事先区别对待。

 

 

 

从任务调度的触发时机来分,这里主要是针对作业使用的触发器,主要有以下两种:

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

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

 

注:并非每种任务都可以使用这两种触发器,如java.util.TimerTask任务就只能使用第一种。Quartzspring task都可以支持这两种触发条件。

 

 

 

 

二.用法说明

 

详细介绍每种任务调度工具的使用方式,包括Quartzspring task两种。

Quartz

第一种,作业类继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean

 

第一步:定义作业类

 

 

Java代码 

import org.quartz.JobExecutionContext; 

import org.quartz.JobExecutionException; 

import org.springframework.scheduling.quartz.QuartzJobBean; 

public class Job1 extends QuartzJobBean { 

 

private int timeout; 

private static int i = 0; 

//调度工厂实例化后,经过timeout时间开始执行调度 

public void setTimeout(int timeout) { 

this.timeout = timeout; 

 

/**

* 要调度的具体任务

*/ 

@Override 

protected void executeInternal(JobExecutionContext context) 

throws JobExecutionException { 

  System.out.println("定时任务执行中…"); 

 

 第二步:spring配置文件中配置作业类JobDetailBean

Xml代码 

<bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean"> 

<property name="jobClass" value="com.gy.Job1" /> 

<property name="jobDataAsMap"> 

<map> 

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

</map> 

</property> 

</bean> 

 

 说明:org.springframework.scheduling.quartz.JobDetailBean有两个属性,jobClass属性即我们在java代码中定义的任务类,jobDataAsMap属性即该任务类中需要注入的属性值。

 

第三步:配置作业调度的触发方式(触发器)

 

Quartz的作业触发器有两种,分别是

 

org.springframework.scheduling.quartz.SimpleTriggerBean

 

org.springframework.scheduling.quartz.CronTriggerBean

 

第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。

 

配置方式如下:

 

 

Xml代码 

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

<property name="jobDetail" ref="job1" /> 

<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> 

<property name="repeatInterval" value="2000" /><!-- 2秒调度一次 --> 

</bean> 

 

第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。

 

配置方式如下:

Xml代码 

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

<property name="jobDetail" ref="job1" /> 

<!—每天12:00运行一次 --> 

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

</bean> 

 

 关于cronExpression表达式的语法参见附录。

 

第四步:配置调度工厂

Xml代码 

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

<property name="triggers"> 

<list> 

<ref bean="cronTrigger" /> 

</list> 

</property> 

</bean> 

 

 说明:该参数指定的就是之前配置的触发器的名字。

 

第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。

 

 

 

 

第二种,作业类不继承特定基类。

 

Spring能够支持这种方式,归功于两个类:

 

org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean

 

org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean

 

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

 

第一步:编写任务类

Java代码 

public class Job2 { 

public void doJob2() { 

System.out.println("不继承QuartzJobBean方式-调度进行中..."); 

 

 可以看出,这就是一个普通的类,并且有一个方法。

 

第二步:配置作业类

Xml代码 

<bean id="job2" 

class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 

<property name="targetObject"> 

<bean class="com.gy.Job2" /> 

</property> 

<property name="targetMethod" value="doJob2" /> 

<property name="concurrent" value="false" /><!-- 作业不并发调度 --> 

</bean> 

 

 说明:这一步是关键步骤,声明一个MethodInvokingJobDetailFactoryBean,有两个关键属性:targetObject指定任务类,targetMethod指定运行的方法。往下的步骤就与方法一相同了,为了完整,同样贴出。

 

第三步:配置作业调度的触发方式(触发器)

 

Quartz的作业触发器有两种,分别是

 

org.springframework.scheduling.quartz.SimpleTriggerBean

 

org.springframework.scheduling.quartz.CronTriggerBean

 

第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。

 

配置方式如下:

Xml代码 

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

<property name="jobDetail" ref="job2" /> 

<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> 

<property name="repeatInterval" value="2000" /><!-- 2秒调度一次 --> 

</bean> 

 

 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。

 

配置方式如下:

Xml代码 

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

<property name="jobDetail" ref="job2" /> 

<!—每天12:00运行一次 --> 

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

</bean> 

 

以上两种调度方式根据实际情况,任选一种即可。

 

第四步:配置调度工厂

Xml代码 

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

<property name="triggers"> 

<list> 

<ref bean="cronTrigger" /> 

</list> 

</property> 

</bean> 

 

说明:该参数指定的就是之前配置的触发器的名字。

 

第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。

 

 

 

到此,springQuartz的基本配置就介绍完了,当然了,使用之前,要导入相应的spring的包与Quartz的包,这些就不消多说了。

 

其实可以看出Quartz的配置看上去还是挺复杂的,没有办法,因为Quartz其实是个重量级的工具,如果我们只是想简单的执行几个简单的定时任务,有没有更简单的工具,有!

 

请看我第下文Spring task的介绍。

 

 

Spring-Task

 

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

 

形式,下面将分别介绍这两种方式。

第一种:配置文件方式

 

第一步:编写作业类

 

即普通的pojo,如下:

Java代码 

import org.springframework.stereotype.Service; 

@Service 

public class TaskJob { 

     

    public void job1() { 

        System.out.println(“任务进行中。。。”); 

    } 

 

 第二步:在spring配置文件头中添加命名空间及描述

Xml代码 

<beans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:task="http://www.springframework.org/schema/task"  

    。。。。。。 

    xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 

 

 第三步:spring配置文件中设置具体的任务

Xml代码 

 <task:scheduled-tasks>  

        <task:scheduled ref="taskJob" method="job1" cron="0 * * * * ?"/>  

</task:scheduled-tasks> 

 

<context:component-scan base-package=" com.gy.mytask " /> 

 

说明:ref参数指定的即任务类,method指定的即需要运行的方法,croncronExpression表达式,具体写法这里不介绍了,详情见上篇文章附录。

 

<context:component-scan base-package="com.gy.mytask" />这个配置不消多说了,spring扫描注解用的。

 

到这里配置就完成了,是不是很简单。

第二种:使用注解形式

 

也许我们不想每写一个任务类还要在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(); 

 

 可以看出该注解有三个方法或者叫参数,分别表示的意思是:

 

cron:指定cron表达式

 

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.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。

 

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.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。

 

 

 

下面我来配置一下。

 

第一步:编写pojo

Java代码 

import org.springframework.scheduling.annotation.Scheduled;   

import org.springframework.stereotype.Component; 

 

@Component(“taskJob”) 

public class TaskJob { 

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

    public void job1() { 

        System.out.println(“任务进行中。。。”); 

    } 

 

 第二步:添加task相关的配置:

Xml代码 

<?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:aop="http://www.springframework.org/schema/aop" 

    xmlns:context="http://www.springframework.org/schema/context" 

    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.0.xsd 

        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 

        http://www.springframework.org/schema/context  

http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd 

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 

        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" 

    default-lazy-init="false"> 

 

 

    <context:annotation-config /> 

    <!spring扫描注解的配置   --> 

    <context:component-scan base-package="com.gy.mytask" /> 

     

<!—开启这个配置,spring才能识别@Scheduled注解   --> 

    <task:annotation-driven scheduler="qbScheduler" mode="proxy"/> 

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

 

说明:理论上只需要加上<task:annotation-driven />这句配置就可以了,这些参数都不是必须的。

 

 

 

 Ok配置完毕,当然spring task还有很多参数,我就不一一解释了,具体参考xsd文档http://www.springframework.org/schema/task/spring-task-3.0.xsd

 

附录:

 

cronExpression的配置说明,具体使用以及参数请百度google

 

字段   允许值   允许的特殊字符

 

    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 ? * *"    每天早上1015触发

 

"0 15 10 * * ?"    每天早上1015触发

 

"0 15 10 * * ? *"    每天早上1015触发

 

"0 15 10 * * ? 2005"    2005年的每天早上1015触发

 

"0 * 14 * * ?"    每天从下午2点开始到259分每分钟一次触发

 

"0 0/5 14 * * ?"    每天从下午2点开始到255分结束每5分钟一次触发

 

"0 0/5 14,18 * * ?"    每天的下午2点至2556点至655分两个时间段内每5分钟一次触发

 

"0 0-5 14 * * ?"    每天14:0014:05每分钟一次触发

 

"0 10,44 14 ? 3 WED"    三月的每周三的14101444触发

 

"0 15 10 ? * MON-FRI"    每个周一、周二、周三、周四、周五的1015触发

分享到:
评论
1 楼 简妮3 2016-09-06  
亲们  想问下  定时任务在启动的时候可以传参数么?

相关推荐

    使用java定时器的几种方式

    java中实现定时器的三种方式,qutarz+spring, spring-task, java Timer

    javaweb 定时器的几种方式

    javaweb的几种定时方式,有助于了解定时的工作原理。对于定时器不了解的朋友可以看看

    Spring中的Quartz配置-Spring-定时器-java定时器.doc

    Spring中的Quartz配置-Spring-定时器-java定时器.doc

    Android 实现定时器的四种方式总结及实现实例

    Android中实现定时器的四种方式 第一种方式利用Timer和TimerTask 1、继承关系 java.util.Timer 基本方法 schedule 例如: timer.schedule(task, delay,period); //delay为long,period为long:从现在起过delay毫秒...

    java Quartz定时器任务与Spring task定时的几种实现方法

    本篇文章主要介绍了java Quartz定时器任务与Spring task定时的几种实现方法的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

    Java定时更新数据—定时器

    某个功能执行需要的时间比较长,则决定采用定时器的方式,每隔一段时间系统自动执行此功能,当界面真正触发时,只需要简单的读取结果,而不需要执行复杂的逻辑判断.那如何实现此功能呢?要想实现它,首先我们需要...

    JAVA上百实例源码以及开源项目

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    JAVA上百实例源码以及开源项目源代码

     通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 ...

    个人总结的深入java多线程开发

    4)终止多线程程序的两种方式(轮询访问变量和interrupt方法) 23 四Concurrent包详解 25 1)Executor接口 25 2)ExecutorService接口 27 3)Callable对象 28 4)Executors工厂类 29 5)使用ExecutorService的例子 30 6)...

    java范例开发大全源代码

    第1篇 Java编程基础  第1章 Java开发环境的搭建(教学视频:9分钟) 2  1.1 理解Java 2  1.2 搭建Java所需环境 3  1.2.1 下载JDK 3  1.2.2 安装JDK 4  1.2.3 配置环境 5  1.2.4 测试JDK配置...

    java范例开发大全

    13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 模拟淘宝购物买卖双方交易问题 412 实例226 携子之手 ...

    Java范例开发大全 (源程序)

    第1篇 Java编程基础  第1章 Java开发环境的搭建(教学视频:9分钟)... 13.1 多线程的五种基本状态 405  实例222 启动线程 405  实例223 参赛者的比赛生活(线程休眠唤醒) 407  实例224 资源搜索并下载(线程...

    一种基于Java企业内部及时通讯软件设计.doc

    一种基于Java企业内部及时通讯软件设计 摘要:基于Socket的局域网通讯软件能为企业局域网提供一种安全、快速的通信机制, 使用Java Swing 技术设计系统界面,以Derby作为数据库服务器,用Socket编程技术实现网络通讯...

    阿里巴巴,天猫,支付宝面试题

    14. spring的bean配置的几种方式 15. web.xml的配置 16. spring的监听器。 17. zookeeper的实现机制,有缓存,如何存储注册服务的 18. IO会阻塞吗?readLine是不是阻塞的 19. 用过spring的线程池还是java的线程池? ...

    Java范例开发大全(全书源程序)

    13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 模拟淘宝购物买卖双方交易问题 412 实例226 携子...

    java范例开发大全(pdf&源码)

    13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 模拟淘宝购物买卖双方交易问题 412 实例226 携子之手 ...

    maven + spring boot + jdbc + mysql 定时器 的一个爬虫小程序 .zip

    爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

    基于Android操作系统的智能手机开发

    4. 加分系统——击中敌方汽车或是吃到宝贝(几种不同的汽车分数不同) 5. 障碍物——汽车隐身(草坪)、子弹击破(砖墙)、子弹打不破(铁墙) 6. 音效snd1—snd2格式为midi用于过场音乐及子弹发射、爆炸音效

    一个MIDP俄罗斯方块游戏的设计和实现

    本游戏涉及到以下几种数据结构。 游戏区域 游戏区域为手机或者PDA屏幕的一部分,该区域为正方形,边长一定能被16整除(因为俄罗斯游戏区域刚好为16个小砖块长,16个小砖块宽的方形)。无论在水平方向还是垂直...

Global site tag (gtag.js) - Google Analytics