Spring 和 Quartz 实现定时任务

  • Java 定时的四种方式
  • Quartz
    • 对于继承QuartzJobBean需要做
      • 需要实现定时任务的类继承orgspringframeworkschedulingquartzQuartzJobBean实现定时执行的方法xml里要么声明这个定时任务类要么使用注解扫描的方式声明
      • xml里声明新的beanclass为orgspringframeworkschedulingquartzJobDetailBean
    • 对于不继承需要做
      • 需要实现定时任务的类主要是实现定时执行的方法
      • xml里使用MethodInvokingJobDetailFactoryBean配置作业类例如
      • xml里配置触发器Trigger用于指定什么时候执行定时任务
      • xml里配置调度工厂Scheduler统一调度触发器的地方
  • 使用Spring的Task
    • xml文件文件头里新加入命名空间
    • xml方式
      • 实现定时任务类通过xml配置或者注解声明这个类
      • 配置任务
    • 注解方式
      • 实现定时任务类然后对方法加上Scheduled注解里面还可配置cron表达式或者固定延迟时间固定频率
      • xml里配置task
  • 参考博客

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

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">
    <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" />  
    <property name="repeatInterval" value="2000" />  
bean> 

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
    <property name="jobDetail" ref="job" />  
      
    <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>   
        
        <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" />  
 
<task:annotation-driven executor="executor" scheduler="scheduler" />

参考博客

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

你可能感兴趣的:(Java,知识,Java代码片段)