Spring 和 Quartz 实现定时任务

注:文中示例和总结源自结尾的参考博客,感谢各位博主的分享

Quartz是一个开源的,用于处理定时任务的项目,因为相比于Java本身的Timer功能更强大一些,而且和Spring整合在了一起,所以应用广泛。我正好最近接触到的任务中碰到了它,做个记录

Java 定时的四种方式

  1. 使用Java自带的定时器Timer,自己实现TimerTask(抽象类,扩展了Runnable),传入Timer的方法中,进行调度,缺点是不能满足类似于“在某时某刻执行”的要求,另外可能出现定时不准,因为Timer是单线程的,所以就和JS的定时器一样,存在延迟
  2. 接着1说,改进是可以通过Java的线程池ScheduledThreadPoolExecutor来替代,可以指定多线程,消除定时不准的问题
  3. 使用Quartz,也就是本文接下来要讲的
  4. 使用Spring3.0后自带的Task,类似于Quartz,接下来也会介绍

Quartz

使用Quartz分两种:继承QuartzJobBean和不继承的,二者仅编写定时任务类和xml配置作业类两步不同
使用Quartz的一个注意点是:与Spring3.1以下版本整合必须使用Quartz1,因为Spring3.0版本以下,有一个类继承自Quartz1版本的类,在Quartz更高版本,那个类被改为接口了(见结尾参考博客:Spring与Quartz的整合实现定时任务调度

使用的步骤分为以下几个:

对于继承QuartzJobBean,需要做

1. 需要实现定时任务的类继承org.springframework.scheduling.quartz.QuartzJobBean,实现定时执行的方法,xml里要么声明这个定时任务类,要么使用注解扫描的方式声明

2. xml里声明新的bean,class为org.springframework.scheduling.quartz.JobDetailBean

描述定时任务类,例如:

<bean name="job" class="org.springframework.scheduling.quartz.JobDetailBean">  
    <property name="jobClass" value="com.example.QuartzTimer" />  <!-- 这个属性,指定定时任务类 -->
    <property name="jobDataAsMap"><!-- 这个属性,为定时任务类注入属性,注意对应定时任务类,需要有属性的set方法 -->
    <map>
        <entry key="timeout" value="0" />  
    </map>  
    </property>  
</bean> 

对于不继承,需要做

1. 需要实现定时任务的类,主要是实现定时执行的方法

2. xml里使用MethodInvokingJobDetailFactoryBean配置作业类,例如

<bean id="job" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
    <property name="targetObject">  
        <bean class="com.example.QuartzTimer" />  <!-- 这个属性,指定定时任务类 -->
    </property>  
    <property name="targetMethod" value="doJob" />  
    <property name="concurrent" value="false" /><!-- 作业不并发调度 -->  
</bean>  

接下来的三步,都一样

3. xml里配置触发器Trigger,用于指定什么时候执行定时任务

触发器分两种:org.springframework.scheduling.quartz.SimpleTriggerBeanorg.springframework.scheduling.quartz.CronTriggerBean。其中SimpleTriggerBean只支持按频率触发,比如每隔多长时间执行一次,而CronTriggerBean支持使用Cron表达式,指定类似“在每几天的什么时间执行”的触发

这里需要注意的是,触发器Trigger和定时任务的对应关系:一个触发器只能关联一个定时任务,但是一个定时任务可以关联多个触发器(定时任务类对触发器为多对一)
xml配置例如:

<!--  -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  
    <property name="jobDetail" ref="job" />  
    <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->  
    <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 -->  
</bean> 

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
    <property name="jobDetail" ref="job" />  
    <!-- 每天12:00运行一次 -->  
    <property name="cronExpression" value="0 0 12 * * ?" />  
</bean> 

4. xml里配置调度工厂Scheduler,统一调度触发器的地方

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    <property name="triggers"><!-- 所有的触发器配到这里,由调度工厂统一调度 -->
        <list>
            <ref bean="simpleTrigger"/>
            <ref bean="cronTrigger" /> 
        </list>  
    </property>  
</bean>  

最后,关于使用Quartz的最后一点,我们也可以继承TimerTask,实现定时任务的逻辑,然后通过xml里声明org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean,指向这个类,其他触发器调度工厂,配置不变的方式,实现定时任务。

使用Spring的Task

Spring引入注解后,很多功能都可以通过注解来配置完成了,当然xml的配置方式也保留了下来,Task也不例外
首先,不管xml方式还是注解方式,都需要在xml配置文件的文件头加入命名空间和描述

xml文件,文件头里新加入命名空间

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

xml方式

1. 实现定时任务类,通过xml配置或者注解,声明这个类

2. 配置任务

 <task:scheduled-tasks>   
        <!-- job为定时任务类,通过xml配置或者注解方式声明了得 -->
        <task:scheduled ref="job" method="someMethod" cron="0 15 * * * ?"/> 
</task:scheduled-tasks>  

注解方式

1. 实现定时任务类,然后对方法加上Scheduled注解,里面还可配置cron表达式,或者固定延迟时间、固定频率

例如:

@Scheduled(cron = "0 0 3 * * ?")  
public void task() {  
    System.out.println(“任务进行中。。。”);  
}  

2. xml里配置task

<task:executor id="executor" pool-size="5" />  
<task:scheduler id="scheduler" pool-size="10" />  
<!-- 开启这个配置,spring才能识别@Scheduled注解   --> 
<task:annotation-driven executor="executor" scheduler="scheduler" />

参考博客

上述文档里的内容,其实是从三个博客里提出来的,感谢这三位博主的分享
1. Spring定时任务的几种实现
2. 使用Spring的@Scheduled实现定时任务
3. Spring与Quartz的整合实现定时任务调度

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值