Spring 使用 Quartz,在自定义服务中使用 SchedulerFactoryBean

Spring with Quartz, using SchedulerFactoryBean in custom service

我有一个注入了 bean 的工作。我已经使用这个 solution.

在此解决方案中,作业触发器是在配置 class 中配置 SchedulerFactoryBean bean 期间设置的。

但我想通过 colling scheduleTrackRetry 方法在我的自定义 SchedulerService 服务中安排它。

我尝试了类似的操作(见下文),但作业没有在适当的时候启动。

@Service
public class SchedulerService {

  @Autowired
  SchedulerFactoryBean quartzScheduler;

  @Autowired
  JobDetailFactoryBean jobDetailFactoryBean;

  @Autowired
  CronTriggerFactoryBean cronTriggerFactoryBean;

  public void scheduleTrackRetry() {
    cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
    quartzScheduler.setTriggers(cronTriggerFactoryBean.getObject());
}

那么,请告诉我怎样才能实现所需的行为?

这是我的工作和会议 classes:

@Component
public class TrackRetryJob implements Job {

  private static final Logger LOGGER = LoggerFactory.getLogger(TrackRetryJob.class);

  @Autowired
  private TimeformBatchService timeformBatchService;

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    LOGGER.info("Run retry for fetching greyhound tracks");
    timeformBatchService.consumeTracks();
  }

}

@Configuration
public class QuartzConfig {

  @Autowired
  private ApplicationContext applicationContext;

  @Bean
  public SchedulerFactoryBean quartzScheduler() {
    SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
    // custom job factory of spring with DI support for @Autowired!
    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    quartzScheduler.setJobFactory(jobFactory);
    quartzScheduler.setTriggers(getTrigger().getObject());
    return quartzScheduler;
  }

  @Bean
  public JobDetailFactoryBean retryTrackFetch() {
    JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
    jobDetailFactory.setJobClass(TrackRetryJob.class);
    jobDetailFactory.setGroup("group1");
    return jobDetailFactory;
  }

  @Bean
  public CronTriggerFactoryBean getTrigger() {
    CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
    cronTriggerFactoryBean.setJobDetail(retryTrackFetch().getObject());
    cronTriggerFactoryBean.setCronExpression("0 53 * * * ?");
    cronTriggerFactoryBean.setGroup("group1");
    return cronTriggerFactoryBean;
  }

}

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

  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);
    beanFactory.autowireBean(job);
    return job;
  }
}

我找到了解决方案here

我无法将 SchedulerFactoryBean 用作普通 bean。当我尝试注入它时,spring 注入了 Scheduler bean。因此我的服务应该是这样的:

@Service
public class SchedulerService {

  @Autowired
  Scheduler scheduler;

}