1、普通的定时任务我们用Sping 自带的scheduler就可以完成,但是需要从数据库动态配置可能要用到Quartz了。
2、遇到的问题:单独只定时一个任务,可以直接写一个类,设置 jobDetail和cronTrigger,放到SchedulerFactoryBean中方可 。具体示例:
package pft.web.timing;
import org.quartz.Trigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfigration {
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledJob task) {//ScheduledJob 为定时任务的类
// ScheduleTask为需要执行的任务
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否并发执行
* 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
* 如果此处为true,则下一个任务会bing执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
*/
jobDetail.setConcurrent(true);
jobDetail.setName("scheduler");// 设置任务的名字
jobDetail.setGroup("scheduler_group");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用
/*
* 这两行代码表示执行task对象中的scheduleTest方法。定时执行的逻辑都在scheduleTest。
*/
jobDetail.setTargetObject(task);
jobDetail.setTargetMethod("scheduleTest");//scheduleTest 定时任务中要执行的方法
return jobDetail;
}
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
tigger.setJobDetail(jobDetail.getObject());
tigger.setCronExpression("0/6 * * * * ?");// 表示每隔6秒钟执行一次
//tigger.set
tigger.setName("myTigger");// trigger的name
return tigger;
}
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
//设置是否任意一个已定义的Job会覆盖现在的Job。默认为false,即已定义的Job不会覆盖现有的Job。
bean.setOverwriteExistingJobs(true);
// 延时启动,应用启动5秒后 ,定时器才开始启动
bean.setStartupDelay(5);
// 注册定时触发器
bean.setTriggers(cronJobTrigger);
return bean;
}
//多任务时的Scheduler,动态设置Trigger。一个SchedulerFactoryBean可能会有多个Trigger
@Bean(name = "multitaskScheduler")
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
return schedulerFactoryBean;
}
}
3、要有多个定时任务时:(参考地址:https://blog.csdn.net/mengruobaobao/article/details/79106343)
一、首先新建 MyJobFactory ,
目的是:
在具体的Job 中 需要Spring 注入一些Service。所以我们要自定义一个jobfactory, 让其在具体job 类实例化时 使用Spring 的API 来进行依赖注入。
package pft.web.timing;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
public class MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
// 进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
二、配置 SchedulerFactoryBean
package pft.web.timing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerListener {
@Autowired
private MyJobFactory myJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(myJobFactory);//将job实例化,能够操作进行Spring 注入
return schedulerFactoryBean;
}
}
3、分别给定时任务设置 jobDetail和cronTrigger ,注册定时触发器 SchedulerFactoryBean
package pft.web.timing;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
@Service
public class MyScheduler {
@Autowired
SchedulerFactoryBean schedulerFactoryBean;
public void scheduleJobs() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
startJob1(scheduler);
startJob2(scheduler);
}
private void startJob1(Scheduler scheduler) throws SchedulerException{
JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class)
.withIdentity("job1", "group1").build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,cronTrigger);
}
private void startJob2(Scheduler scheduler) throws SchedulerException{
JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class)
.withIdentity("job2", "group1").build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?");
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1")
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,cronTrigger);
}
}
四、控制层调用 scheduleJobs 方法,开启定时器
亲测、能够在job中的注入spring