这是我处理这种情况的一种方法。
首先,在我的Spring配置中,指定一个
SchedulerFactoryBean可以将注入
Scheduler其他bean的。
<bean name="SchedulerFactory" > <property name="applicationContextSchedulerContextKey"> <value>applicationContext</value> </property></bean>
然后,当我在应用程序中创建作业时,我将作业的详细信息存储在数据库中。该服务由我的一个控制器调用,它调度作业:
@Componentpublic class FollowJobService { @Autowired private FollowJobRepository followJobRepository; @Autowired Scheduler scheduler; @Autowired ListableBeanFactory beanFactory; @Autowired JobSchedulerLocator locator; public FollowJob findByClient(Client client){ return followJobRepository.findByClient(client); } public void saveAndSchedule(FollowJob job) { job.setJobType(JobType.FOLLOW_JOB); job.setCreatedDt(new Date()); job.setIsEnabled(true); job.setIsCompleted(false); JobContext context = new JobContext(beanFactory, scheduler, locator, job); job.setQuartzGroup(context.getQuartzGroup()); job.setQuartzName(context.getQuartzName()); followJobRepository.save(job); JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, job)); }}在
JobContext我生成包含详细的有关工作,并最终传递给调度作业的工具。这是实际调度作业的实用程序方法的代码。请注意,在我的服务中,我会自动连线
JobScheduler并将其传递给
JobContext。还要注意,我使用存储库将作业存储在数据库中。
@Overridepublic void schedule(JobContext context) { Client client = context.getNetworkSociallyJob().getClient(); this.logScheduleAttempt(context, client); JobDetail jobDetails = JobBuilder.newJob(this.getJobClass()).withIdentity(context.getQuartzName(), context.getQuartzGroup()).build(); jobDetails.getJobDataMap().put("job", context.getNetworkSociallyJob()); jobDetails.getJobDataMap().put("repositories", context.getRepositories()); Trigger trigger = TriggerBuilder.newTrigger().withIdentity(context.getQuartzName() + "-trigger", context.getQuartzGroup()) .withSchedule(cronSchedule(this.getSchedule())).build(); try { context.getScheduler().scheduleJob(jobDetails, trigger); this.logSuccess(context, client); } catch (SchedulerException e) { this.logFailure(context, client); e.printStackTrace(); }}因此,在执行完所有这些代码后,发生了两件事,我的工作存储在数据库中,并使用石英调度程序进行了调度。现在,如果应用程序重新启动,我想使用调度程序重新调度我的作业。为此,我注册了一个实现的bean,
ApplicationListener<ContextRefreshedEvent>每次容器重新启动或启动时,Spring都会调用该bean
。
<bean id="jobInitializer" />
JobInitializer.class
public class JobInitializer implements ApplicationListener<ContextRefreshedEvent> { Logger logger = LoggerFactory.getLogger(JobInitializer.class); @Autowired DataMiningJobRepository repository; @Autowired ApplicationJobRepository jobRepository; @Autowired Scheduler scheduler; @Autowired JobSchedulerLocator locator; @Autowired ListableBeanFactory beanFactory; @Override public void onApplicationEvent(ContextRefreshedEvent event) { logger.info("Job Initilizer started."); //TODO: Modify this call to only pull completed & enabled jobs for (ApplicationJob applicationJob : jobRepository.findAll()) { if (applicationJob.getIsEnabled() && (applicationJob.getIsCompleted() == null || !applicationJob.getIsCompleted())) { JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, applicationJob)); } }}}此类自动关联调度程序和存储库,该存储库可获取实现该
ApplicationJob接口的每个作业的实例。使用这些数据库记录中的信息,我可以使用调度程序实用程序来重建作业。
因此,基本上,我将作业手动存储在数据库中,并通过
Scheduler在适当的Bean中注入实例来手动安排作业。要重新计划它们,我查询数据库,然后使用计划它们
ApplicationListener以重新启动和启动容器。



