一.Quartz的介绍和使用思路:
1.介绍:
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
Quartz是一个完全由java编写的开源作业调度框架。不要让作业调度这个术语吓着你。尽管Quartz框架整合了许多额外功能, 但就其简易形式看,你会发现它易用得简直让人受不了!。简单地创建一个实现org.quartz.Job接口的java类。Job接口包含唯一的方法:
public void execute(JobExecutionContext context)
throws JobExecutionException;
在你的Job接口实现类里面,添加一些逻辑到execute()方法。一旦你配置好Job实现类并设定好调度时间表,Quartz将密切注意剩余时间。当调度程序确定该是通知你的作业的时候,Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情。无需报告任何东西给调度器或调用任何特定的东西。仅仅执行任务和结束任务即可。如果配置你的作业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。
2.Quartz使用思路:
1). job - 任务 - 你要做什么事?
2). Trigger - 触发器 - 你什么时候去做?
3). Scheduler - 任务调度 - 你什么时候需要做什么事?
示例:
2.1 添加依赖:
org.quartz-scheduler
quartz
2.2.1
slf4j-api
org.slf4j
org.springframework
spring-context-support
org.springframework
spring-tx
2.2 首先要创建执行什么任务的类也就是Job类:
/**
* 定义任务类
*
* Created by ${ligh} on 2019/1/25 下午4:02
*/
public class QuartzDemo implements Job {
/**
* 任务被触发时所执行的方法
*
* @param context
* @throws JobExecutionException
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Execute ... " + new Date());
}
}
2.3 使用Quartz来调度任务:
/**
* Created by ${ligh} on 2019/1/25 下午4:09
*/
public class TestQuartz {
public static void main(String[] args) throws Exception{
//1.创建Job对象: 你要做什么事?
JobDetail job = JobBuilder.newJob(QuartzDemo.class).build(); //需要传入任务类的方法,就是做什么的类
//2.创建Trigger对象,在什么时间做?
/**
* 简单的trigger触发时间: 通过Quartz提供一个方法来完成简单的重复调用
*
* cron Trigger : 按照Cron的时间表达式给定触发的时间
*
*/
//下面采用通过Quartz提供的方法来执行,每秒钟执行一次,并且一直执行
// Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatMinutelyForever())
// .build();// 所需的参数就是给定的时间
//下面是通过Cron表达式来控制时间, 没两秒执行一次
Trigger trigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
.build();// 所需的参数就是给定的时间
//3.创建Scheduler对象,整合上面两步,在什么时间做什么事?
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//把job和trigger交给Scheduler来调度
scheduler.scheduleJob(job,trigger);
//4.启动
scheduler.start();
}
}
测试结果:
二.Springboot整合Quartz定时框架:
第一步: 添加坐标
org.quartz-scheduler
quartz
2.2.1
slf4j-api
org.slf4j
org.springframework
spring-context-support
org.freemarker
spring-tx
第二步:简单实践
2.1 在quartz包中创建Job任务:
/**
* 定义任务类
*
* Created by ${ligh} on 2019/1/25 下午4:02
*/
public class QuartzDemo implements Job {
/**
* 任务被触发时所执行的方法
*
* @param context
* @throws JobExecutionException
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Execute ... " + new Date());
}
}
2.2 在config包下创建Quartz的配置类:
import com.ligh.quartz.QuartzDemo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
/**
*
* Quartz的配置类
*
* Created by ${ligh} on 2019/1/25 下午5:28
*/
@Configuration
public class QuartzConfig {
/**
* 1.创建job对象 做什么
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
//关联自己的job类
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* 2.创建Trigger对象 什么时候做
*
* 简单Trigger
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
//关联JobDetail对象
factory.setJobDetail(jobDetailFactoryBean.getObject());
//设置触发时间 该参数表示毫秒,2000表示2秒
factory.setRepeatInterval(2000);
//设置重复次数
factory.setRepeatCount(5);
return factory;
}
/**
* 3.创建Scheduler对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//关联trigger
factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
return factoryBean;
}
}
2.3 修改启动类:
在启动类的上面加上@EnableScheduling注解,扫描Scheduler,不然启动会报错
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class QuartsApplication {
public static void main(String[] args) {
SpringApplication.run(QuartsApplication.class, args);
}
}
拓展: 使用复杂的Cron表达式做定时任务(上面是简单的定时)
@Configuration
public class QuartzConfig {
/**
* 1.创建job对象 做什么
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
//关联自己的job类
factory.setJobClass(QuartzDemo.class);
return factory;
}
/**
* Cron Trigger
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
//关联JobDetail
factory.setJobDetail(jobDetailFactoryBean.getObject());
// 秒 分钟 小时 天 月 星期
factory.setCronExpression("10,15,20 34 11 * * ?");
//表示每年每月每天的11点34分的10,15,20秒都会执行一次
return factory;
}
/**
* 3.创建Scheduler对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//关联trigger
factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
return factoryBean;
}
}
三.任务类(Job)中注入对象:
直接注入想要实现的业务逻辑的service是注入不进去的,所以要单独的编写一个类来将实现类注入到IOC容器中。
另外需要把该类传给Scheduler,在Scheduler中重新设置Job
注入不进去的原因:
实例化QuartzConfig类时,并没有通过Spring,所以也不会去容器中去读取对应的service实现类,所以可以通过重写createJobInstance方法即可
3.1 定义业务逻辑实现:
@Service
public class UserServiceImpl implements UserService{
@Override
public void insertUser() {
System.out.println("insert user method...");
}
}
3.2 Job类的修改:
/**
* 定义任务类
* Created by ${ligh} on 2019/1/25 下午4:02
*/
public class QuartzDemo implements Job {
@Autowired
private UserService userService;
/**
* 任务被触发时所执行的方法
*
* @param context
* @throws JobExecutionException
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Execute ... " + new Date());
userService.insertUser();
}
}
3.3 创建一个类继承AdaptableJobFactory类,并重写createJobInstance方法
@Component
public class MyDaaptableJobFactory extends AdaptableJobFactory{
//AutowireCapableBeanFactory 可以将一个对象添加到Spring的IOC容器中,并且完成该对象的注入
@Autowired
private AutowireCapableBeanFactory autowiredCaptableBeanFactory;
/**
* 该方法需要将实例化的任务对象手动的添加到Spring的IOC容器中,并且完成对象的注入
*
* @param bundle
* @return
* @throws Exception
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object o = super.createJobInstance(bundle);
//将o对象添加到springIOC容器中,并完成注入
autowiredCaptableBeanFactory.autowireBean(o);
return o;
}
}
3.4 修改QuartzConfig类中的Scheduler:
/**
* 3.创建Scheduler对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyDaptableJobFactory myDaptableJobFactory){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//关联trigger
factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
//传入新创建的类,不然service实现类注入不进去
factoryBean.setJobFactory(myDaptableJobFactory);
return factoryBean;
}