定时任务处理,quartz及Spring整合quartz去快速解决企业开发中的任务调度问题。
quartz是开源且具有丰富特性的“任务调度库”,能够集成于任何的Java应用,任务job被定义为标准的Java组件,能够执行任何你想要实现的功能。quartz调度包含许多企业级的特性,如JTA事务、集群的支持。
简言之,quartz就是基于Java实现的任务调度框架,用于执行任何你想要执行的任务。
第一步:导入jar包;
第二步:获取一个实例;
第三步:创建一个任务;
第四步:任务加载到对象当中;
quartz的设计模式
quartz的核心概念
Scheduler用于与调度程序交互的主程序接口,Scheduler调度程序-任务执行计划表,只有安排进执行计划的任务Job(通过scheduler.schedulerJob()方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发trigger触发器),该任务才会执行;
Job我们预先定义的希望在未来时间能被调度程序执行的任务类,可以自定义;
JobDetail:使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建的;
JobBuilder:用于声明一个任务实例,也可以定义关于该任务的详情如任务名、组名等,这个声明的实例将会作为实际执行的认为;
JobDataMap:可以包含不限量的(序列化的)数据对象,在Job实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法;
Trigger:触发器,Trigger对象是用来触发执行Job的。当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件,表明任务在什么时候会执行。定义了一个已经被安排的任务将会在什么时候执行的时间条件,比如每2秒就执行一次;
TriggerBuilder:触发器创建器,用于创建触发器trigger实例;
JobListener、TriggerListener、SchedulerListener监听器,用于对组件的监听。
(1)导包、创建HelloJob任务类
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.1</version>
</dependency>
<!-- 不引入quartz-jobs也可以 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.1</version>
</dependency>
public class HelloJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// TODO Auto-generated method stub
//输出当前时间
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = dateFormat.format(date);
System.out.println("正在执行数据库备份工作,时间为:"+ dateString);
}
}
第二步:创建任务调度类(触发器、调度器)
public class HelloSchedulerDemo {
public static void main(String[] args) throws Exception {
//1.调度器(Scheduler),从工厂中获取调度的实例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2. 任务实例(JobDetail)
JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//加载任务类,与HelloJob实现绑定,HelloJob得实现Job接口
.withIdentity("job1", "group1")//任务的名称(唯一实例)
.build();
//3. 触发器(Trigger)
Trigger trigger = TriggerBuilder.newTrigger()
.startNow()//马上启动
.withIdentity("trigger1", "group1")//触发器的名称(唯一标识)
.withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5))//每5秒重复执行
.build();
//让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
scheduler.scheduleJob(jobDetail,trigger);
//启动
scheduler.start();
}
}
<!-- 定时任务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.1</version>
</dependency>
package com.xingze.job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class FirstJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("定时任务1开始执行......");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="firstJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.xingze.job.FirstJob"/>
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="0"/>
</map>
</property>
</bean>
<!-- 按照一定频率的触发器 -->
<!-- <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">-->
<!-- <property name="jobDetail" ref="firstJob"/>-->
<!-- <property name="startDelay" value="0"/>-->
<!-- <property name="repeatInterval" value="2000"/>-->
<!-- </bean>-->
<!-- Cron表达式触发器 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="firstJob"/>
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<!-- 配置调度工厂-->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- <ref bean="simpleTrigger"/>-->
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
</beans>
org.springframework.scheduling.quartz.JobDetailBean有两个属性.
Quartz的作业触发器有两种(两种任选其一就行)
# 周六、周日每5分钟执行一次
0 0/5 * ? * SAT,SUN
# 每天 每5分钟执行一次
0 0/5 23-10 ? * *
有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态Job每次调用时都会创建一个新的JobDataMap。