关于多定时任务开发
现有业务需求在用户获取授权token之后,token会在半个小时之后过期,现需要创建多个job对token进行刷新。
1.首先获取授权token,并缓存
2.缓存成功之后创建一个定时job,时间暂定为当前时间的30分钟之后
3.创建job执行的task
代码示例:
/** * 创建job的工厂 * @author wz * @time 2018年1月30日下午2:33:56 */ public class SchedulerFactory { private static Scheduler getScheduler(){ //首先要把SchedulerFactoryBean 初始化 SchedulerFactoryBean schedulerFactoryBean=ApplicationContextConifg.getApplicationContext().getBean(SchedulerFactoryBean.class); if (schedulerFactoryBean==null){ synchronized (SchedulerFactoryBean.class) { if (schedulerFactoryBean==null){ schedulerFactoryBean = SchedulerFactoryBeanBuilder.build(); } } } return schedulerFactoryBean.getObject(); } public static boolean createJob(String jobType, String jobOID, Map<String, String> jobAttributes, Date triggerStartTime, Class jobClass) { boolean success = false; Scheduler scheduler = getScheduler(); if (scheduler==null){ return success; } JobDataMap jobDataMap = new JobDataMap(); if (jobAttributes!=null){ for (Entry<String, String> entry: jobAttributes.entrySet()){ jobDataMap.put(entry.getKey(), entry.getValue()); } } String name = jobType+jobOID; try { Trigger trigger = newTrigger() .forJob(name) .startAt(triggerStartTime).build(); JobDetail jobDetail = newJob(jobClass) .withIdentity(name) .usingJobData(jobDataMap).build(); scheduler.scheduleJob(jobDetail, trigger); success = true; } catch (Exception e) { TicketdashiLog.error(e.getMessage(), e); } return success; } }
初始化的bean
@Autowired private ApplicationContext context; @Bean public SchedulerFactoryBean quartzScheduler() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setApplicationContext(context); //配置文件 schedulerFactoryBean.setConfigLocation(context.getResource("xxx")); schedulerFactoryBean.setOverwriteExistingJobs(true); //job的名字 schedulerFactoryBean.setSchedulerName("xxx")); AutowiredSpringBeanJobFactory jobFactory = new AutowiredSpringBeanJobFactory(); jobFactory.setApplicationContext(context); schedulerFactoryBean.setJobFactory(jobFactory); schedulerFactoryBean.setGlobalJobListeners(new LogJobListener()); return schedulerFactoryBean; }
创建自动注入spring job的工厂
import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.quartz.SpringBeanJobFactory; public class AutowiredSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware { private transient AutowireCapableBeanFactory beanFactory; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { beanFactory = applicationContext.getAutowireCapableBeanFactory(); } @Override protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { final Object job = super.createJobInstance(bundle); beanFactory.autowireBean(job); return job; } }
/** * * @author wz * @time 2018年1月30日 */ public DTO getToken(String code){ //1.先从缓存获取 Object obj=RedisService.get(code); if(obj != null){ return obj; } //根据code获取token DTO token=service.getToken(code); //把token存入缓存 RedisService.set(code,token); Map<String, String> jobAttributes = new HashMap<>(); jobAttributes.put("redisKey", code); jobAttributes.put("index", "1"); long later30m=new Date().getTime()+ 30 * 60 * 1000; SchedulerFactory.createJob("refresh_token", code, jobAttributes,new Date(later30m), RefreshTokenJob.class); return token; }
@PersistJobDataAfterExecution @DisallowConcurrentExecution public class RefreshTokenJob extends QuartzJobBean{ @Autowired private MsjrRefreshtokenClient msjrRefreshtokenClient; private static final String JOB_NAME="refresh_token"; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { String key = context.getJobDetail().getJobDataMap() .getString("redisKey"); int index=Integer.parseInt(context.getJobDetail().getJobDataMap() .getString("index")); //重新获取缓存 //刷新redis中的token } }