【Quartz作业调度基本使用+调度Spring整合和实例】

时间:2023-02-23 11:15:26

Quartz作业调度基本使用

一、引言

实际业务开发中会遇到定时任务的情形,这种时候可以使用Quartz来帮助我们便捷地完成。


二、Quartz核心概念

① Job
Job表示一个工作(任务),需要执行的具体内容。开发中我们可以通过实现Job接口,来指定我们具体要执行的工作。不过也可以直接写一个类,Spring会帮助我们做具体的注入。


public interface Job {
void execute(JobExecutionContext context)
throws JobExecutionException;
}

当然我们可以使用Spring配置将Job注入容器,如下:


<bean id="helloJob" class="com.example.jobs.HelloJob"/>

② JobDetail
JobDetail表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容。我们需要通过JobDetail来对Job进行绑定,具体如下:


JobDetail job = newJob(HelloJob.class)
.withIdentity("helloJob", "group1")
.build();

当然我们也可以通过配置Spring将其注入到应用容器当中,如下:


<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 注入目标对象 -->
<property name="targetObject" ref="helloJob"/>
<!-- 注入目标方法 -->
<property name="targetMethod" value="sayHello"/>
</bean>

③ Trigger
Trigger定义执行给定作业的计划的组件。


Trigger trigger = newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();

在Spring配置中继续注册我们的触发器,如下:


<bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 注入JobDetail -->
<property name="jobDetail" ref="jobDetail"/>
<!-- 指定触发的时间,基于Cron表达式 -->
<property name="cronExpression">
<!--<value>0 0 2 * * ?</value>-->
<value>0/10 * * * * ?</value>
</property>
</bean>

④ Scheduler
Scheduler代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。


//注册trigger并启动scheduler
scheduler.scheduleJob(job,trigger);
scheduler.start();

在Spring中我们也使用对应的FactoryBean来完成注册,如下:


<!-- 注册一个统一的调度工厂,通过这个调度工厂调度任务 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 注入多个触发器 -->
<property name="triggers">
<list>
<ref bean="myTrigger"/>
</list>
</property>
</bean>


三、Quartz结合Spring使用的一些细节

Ⅰ autoStartup自动启动
通过观察代码,我们不难发现在编码中我们手动去启动了scheduler,如下:


scheduler.start();

而在Spring中,我们使用了SchedulerFactoryBean,工厂Bean来完成scheduler对象的注入。我们并没有显示地去获取scheduler对象,和启动任务调度。因为在Spring bean相应的生命周期内,框架已经帮我们完成了启动与调度。(此处我们不讨论FactoryBean获取bean对象的相关细节,大家应该清楚FactoryBean会通过getObject()来返回我们相应的bean)
SchedulerFactoryBean自动启动任务调度的部分源码
通过查看源码,我们可以看到SchedulerFactoryBean的属性默认支持scheduler的自动启动。我们也可以通过setAutoStartup()方法来禁用此选项。


private boolean autoStartup = true;
/**
* Set whether to automatically start the scheduler after initialization.
* <p>Default is "true"; set this to "false" to allow for manual startup.
*/
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}

Ⅱ JobDetail与Trigger
编码形式的JobDetail与Trigger其实没有直接绑定,理论上两者都可以复用。但是Spring的形式中因为我们使用了特定的FactoryBean,Trigger绑定了JobDetail,能够复用的仅有JobDetail。


四、总结

Quartz的功能其实相当强大,此案例只是使用了基本的功能,对于更深入的内容没有展开讨论。后续会陆续对其进行深入探讨。



》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

接下来讲解:

quartz作业调度spring整合和实例

最近项目中要用到定时任务调度,几番查找决定使用quartz来实现,这里记录一下这个过程,备忘兼学习。

maven引入


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>

spring整合

用spring声明若干相关bean
配置任务类:


<!-- 配置要定时加载的目标类 -->
<bean id="JobTestOne" class="com.trace.app.framework.utils.TaskTime.WarningTask"></bean>
<bean id="JobTestOneDitail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="JobTestOne"></property><!-- 指定任务类 -->
<property name="targetMethod" value="run"></property><!-- 指定任务方法 -->
</bean>

配置触发器,这里使用日历式定时触发器:


<!-- 定义时间间隔触发器 -->
<bean id="JobTestOneTigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="JobTestOneDitail"></property>
<property name="cronExpression">
<value>0 0 0 * * ?</value><!--每天凌晨0:00执行定时任务-->
</property>
</bean>

配置调度器:


<!--调度器配置,list下可加入其他的调度器 -->
<bean id="startJob" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="JobTestOneTigger" />
</list>
</property>
</bean>

这样配置之后,只需要实现job任务即可完成定时任务调度工作。


注意:

1).org.springframework.scheduling.quartz.JobDetailBean有两个属性.

jobClass属性即我们在java代码中定义的任务类.

jobDataAsMap属性即该任务类中需要注入的属性值.

2).Quartz的作业触发器有两种(两种任选其一就行)

org.springframework.scheduling.quartz.SimpleTriggerFactoryBean:只支持按照一定频度调用任务,如每隔30分钟运行一次.

org.springframework.scheduling.quartz.CronTriggerFactoryBean:支持到指定时间运行一次,如每天12:00运行一次等.

3).org.springframework.scheduling.quartz.SchedulerFactoryBean的参数triggers指定的就是之前配置的触发器的名字.


实现的需要调度的任务

【Quartz作业调度基本使用+调度Spring整合和实例】

只需要吧需要定时的任务写出来就可以了,这里是定时查询异常并添加异常记录操作。

备注:Quartz属于重量级的定时任务框架,我们一般都会选择轻量级的如Spring Task定时任务进行开发,但是遇到比较棘手的,这也是一种解决问题的方式。