首先看一下lombok
这篇文件说的很详细
有了lambok这个就可以使用@Date减少我们需要开发的代码
我们使用Quartz来开发定时任务
有三种方法
MethodInvokingJobDetailFactoryBean
implements Job
extends QuartzJobBean
下面我们来看一下第一种(MethodInvokingJobDetailFactoryBean)
任务类
@Configuration
@Component
@EnableScheduling
public class ScheduledTask {
public void sayHello(){
System.out.println("hello");
}
}
定时任务在配置类上添加@EnableScheduling开启对定时任务的支持
@Component作为bean注册到spring容器
@Configuration 配置到<beans>中
配置定时器类使用的是springboot,所有的都是通过spring来管理的,所以返回值通过@Bean来注册到spring容器
@Slf4j
@Configuration
public class QuartzConfig {
}
配置定时器类的方法
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledTask task){
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否并发执行
* 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
* 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
*/
jobDetail.setConcurrent(false);
//设置定时任务的名字
jobDetail.setName("srd-demo");
//设置任务的分组,这些属性都可以在数据库中,在多任务的时候使用
jobDetail.setGroup("srd");
//为需要执行的实体类对应的对象
jobDetail.setTargetObject(task);
/*
* sayHello为需要执行的方法
* 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法
*/
jobDetail.setTargetMethod("sayHello");
log.info("jobDetail 初始化成功!");
return jobDetail;
}
在MethodInvokingJobDetailFactoryBean属性初始化完后,通过MethodInvoker封装TargetObject的TargetMethod方法并在executeInternal中调用MethodInvoker.invoke()来生产job。
返回MethodInvokingJobDetailFactoryBean,将任务job通过@bean注册到spring容器中
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronTriggerFactoryBean(MethodInvokingJobDetailFactoryBean jobDetail){
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(jobDetail.getObject());
//初始化的cron表达式(每天上午10:15触发)
trigger.setCronExpression("0 15 10 * * ?");
//trigger的name
trigger.setName("srd-demo");
log.info("jobTrigger 初始化成功!");
return trigger;
}
配置一个触发器
/**
* 方法名:
* 功能:定义quartz调度工厂
* 描述:
* 创建人:typ
* 创建时间:2018/10/10 14:06
* 修改人:
* 修改描述:
* 修改时间:
*/
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactoryBean(Trigger trigger){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//用于quartz集群,QuartzScheduler启动时更新已存在的job
factoryBean.setOverwriteExistingJobs(true);
//延时启动,应用启动1秒后
factoryBean.setStartupDelay(1);
//注册触发器
factoryBean.setTriggers(trigger);
log.info("scheduler 初始化成功!");
return factoryBean;
}
public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBean<Scheduler>,
BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
}
实现了initializingBean接口,重写了afterPropertiesSet()方法,在这个方法里面
a. 创建了SchedulerFactory
b. 创建Scheduler
c. 如果有jobFactory属性,那么set
d. 注册Scheduler、Job、Trigger的监听器listener(如果有定义的话)
e. 注册Job和Trigger
此外,我们对于Quartz Job的参数设定,也是通过SchedulerFactoryBean类来实现的
[]public static final int DEFAULT_THREAD_COUNT = 10; 默认线程数为10。
[]private String schedulerName; Scheduler的名字,若没有定义则默认用bean的名称(name)。
[]private Resource configLocation; Quartz的配置如quartz.properties的存放位置,若是在xml中配置,则可以写成<property name=“configLocation” value=“classpath:quartz.properties”/>。
[]private Properties quartzProperties; 若是使用Annotation来定义bean,那么初始化quartz.properties可以用bean.setQuartzProperties(Properties)。
[*]private JobFactory jobFactory; 注入一个JobFactory对象。
/**
* 方法名:
* 功能:每隔10s查库,并根据查询结果决定是否重新设置定时任务
* 描述:
* 创建人:typ
* 创建时间:2018/10/10 14:19
* 修改人:
* 修改描述:
* 修改时间:
*/
@Scheduled(fixedRate = 10000)
public void scheduleUpdateCronTrigger() throws SchedulerException {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
//当前Trigger使用的
String currentCron = trigger.getCronExpression();
log.info("currentCron Trigger:{}", currentCron);
//从数据库查询出来的
String searchCron = repository.findAll().get(0).getCron();
log.info("searchCron Trigger:{}", searchCron);
if (currentCron.equals(searchCron)) {
// 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
} else {
//表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
//按新的cronExpression表达式重新构建trigger
// trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
// trigger.getTriggerBuilder()获取静态的TriggerBuilder
trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
// currentCron = searchCron;
}
}
重新配置trigger