前提概述:springboot部分讲解了动态定时器的简单实用,本篇介绍一下怎样结合springcloud配置中心实现多任务配置功能。
初始化配置内容,分为两部分,初始化springbeanJobFactory和定时器配置类
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private static final Logger LOG = LoggerFactory.getLogger(AutowiringSpringBeanJobFactory.class);
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
LOG.info("create job instance");
beanFactory.autowireBean(job);
return job;
}
}
import com.fusion.servicetaskscheduling.util.AppUtil;
import org.quartz.JobDetail;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.spi.JobFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.*;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
@Configuration
@ConditionalOnProperty(name = "quartz.enabled")
public class QuartzConfigrations {
@Autowired
List listOfTrigger;
@Bean
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setOverwriteExistingJobs(true);
factory.setAutoStartup(true);
factory.setJobFactory(jobFactory);
factory.setQuartzProperties(quartzProperties());
// Here we will set all the trigger beans we have defined.
if (!AppUtil.isObjectEmpty(listOfTrigger)) {
factory.setTriggers(listOfTrigger.toArray(new Trigger[listOfTrigger.size()]));
}
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
public static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setStartDelay(0L);
factoryBean.setRepeatInterval(pollFrequencyMs);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
// in case of misfire, ignore all missed triggers and continue :
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
// Use this method for creating cron triggers instead of simple triggers:
public static CronTriggerFactoryBean createCronTrigger(JobDetail jobDetail, String cronExpression) {
CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
factoryBean.setCronExpression(cronExpression);
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
return factoryBean;
}
public static JobDetailFactoryBean createJobDetail(Class jobClass) {
JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
factoryBean.setJobClass(jobClass);
// job has to be durable to be stored in DB:
factoryBean.setDurability(true);
return factoryBean;
}
}
我的项目是添加了两个定时任务,如下为每天定时任务内容
import com.fusion.servicetaskscheduling.configs.QuartzConfigrations;
import com.fusion.servicetaskscheduling.quartz.ResetCron;
import com.fusion.servicetaskscheduling.service.DailyTaskSchedulingService;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
@DisallowConcurrentExecution
public class EveryDayJobWithCronTrigger implements Job {
private final static Logger logger = LoggerFactory.getLogger(EveryDayJobWithCronTrigger.class) ;
@Value("${cron.frequency.everydayjobwithcrontrigger}")
private String frequency ;
@Lazy
@Autowired
DailyTaskSchedulingService taskSchedulingService ;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
logger.info("Running everydayjob | frequency --> " + frequency);
ResetCron.reset(jobExecutionContext,frequency) ;
boolean flag = taskSchedulingService.runTask();
if(flag){
logger.info("----------everydaytask has been successfully execution.----------");
} else {
logger.info("----------everydaytask appear problem, program terminating.----------");
}
}
@Bean(name = "everyDayJobWithCronTriggerBean")
public JobDetailFactoryBean sampleJob() {
return QuartzConfigrations.createJobDetail(this.getClass());
}
@Bean(name = "everyDayJobWithCronTriggerBeanTrigger")
public CronTriggerFactoryBean sampleJobTrigger(@Qualifier("everyDayJobWithCronTriggerBean") JobDetail jobDetail) {
return QuartzConfigrations.createCronTrigger(jobDetail, frequency);
}
}
定时器每次执行任务的时候都判断定时器是否有变化
import org.quartz.*;
public class ResetCron {
public static void reset(JobExecutionContext jobExecutionContext , String frequency){
// JobDetail jobDetail = jobExecutionContext.getJobDetail() ;
Trigger trigger = jobExecutionContext.getTrigger();
Scheduler scheduler = jobExecutionContext.getScheduler() ;
CronTrigger cronTrigger = null;
try {
cronTrigger = (CronTrigger) scheduler.getTrigger(trigger.getKey());
String currentCron = cronTrigger.getCronExpression();// 当前Trigger使用的
if (currentCron.equals(frequency)) {
System.out.println(currentCron+"--------->>>>>>>>>"+frequency);
// 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务
} else {
System.out.println(currentCron+"--------->>>>>>>>>"+frequency);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(frequency);
// 按新的cronExpression表达式重新构建trigger
cronTrigger = (CronTrigger) scheduler.getTrigger(trigger.getKey());
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(trigger.getKey())
.withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(trigger.getKey(), cronTrigger);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
配置中心相关配置内容,taskurl为执行定时任务时调用其他模块的相关内容
cron.frequency.everydayjobwithcrontrigger = 0 0 1 * * ?
cron.frequency.everyweekjobwithcrontrigger = 0 0 3 ? * MON
schedule.dailytaskurl=http://SERVICE-SPARKTASK/getESToHDFSTask,http://SERVICE-SPARKTASK/getData2SqliteNotLogoutTask
schedule.weeklytaskurl=http://SERVICE-SPARKTASK/getUserLabelTask
写的仓促,未完待续