繁体   English   中英

如何避免 Spring 引导应用程序中的默认 Quartz 调度程序?

[英]How to avoid default Quartz Scheduler in Spring Boot application?

我在 Spring Boot 中设置了一个 Quartz 调度程序。 我希望计划的作业能够从应用程序上下文中注入 Bean。 为此,我创建了自己的 Quartz Job Factory:

public final class MyQuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) throws BeansException {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }

}

为了保持对调度器的引用,我有一个调度器管理器 Bean 来初始化调度器:

    public void initScheduler() {
        try (InputStream propsInputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("my-quartz.properties")) {
            log.info("Creating Quartz scheduler...");
            Properties myQuartzProperties = new Properties();
            myQuartzProperties.load(propsInputStream);

            SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
            schedulerFactory.setQuartzProperties(myQuartzProperties);
            schedulerFactory.afterPropertiesSet();
            schedulerFactory.setJobFactory(quartzJobFactory);

            this.scheduler = schedulerFactory.getScheduler();
            this.schedulingConfigMap = new HashMap<>();

            log.info("Quartz scheduler created.");
        } catch (Exception e) {
            log.error("Unable to create Quartz scheduler", e);
            throw new RuntimeException("Scheduler extension initialization error", e);
        }
    }

初始化上下文后,我会初始化调度程序:

public class MyLifecycleListener implements ServletContextListener {

    private final SchedulerManager schedulerManager;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        schedulerManager.initScheduler();
    }

}

石英配置文件如下:

org.quartz.scheduler.instanceName=MyQuartzScheduler

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=12
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true

org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
org.quartz.jobStore.misfireThreshold=60000

启动应用程序时,我看到我的 Quartz Scheduler 已初始化,但问题是我看到第二个 Quartz Scheduler 已初始化(可能是 Spring 默认一个?)。

我的:'MyQuartzScheduler' 有 12 个线程

2022-08-23 14:13:03.239  INFO 24788 --- [           main] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.3.2 created.
2022-08-23 14:13:03.240  INFO 24788 --- [           main] org.quartz.simpl.RAMJobStore             : RAMJobStore initialized.
2022-08-23 14:13:03.241  INFO 24788 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'MyQuartzScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 12 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

2022-08-23 14:13:03.241  INFO 24788 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'MyQuartzScheduler' initialized from an externally provided properties instance.

几毫秒后,另一个名为 'quartzScheduler' 的线程有 10 个线程。

2022-08-23 14:13:03.713  INFO 24788 --- [           main] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.3.2 created.
2022-08-23 14:13:03.713  INFO 24788 --- [           main] org.quartz.simpl.RAMJobStore             : RAMJobStore initialized.
2022-08-23 14:13:03.713  INFO 24788 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'quartzScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
  Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

2022-08-23 14:13:03.713  INFO 24788 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'quartzScheduler' initialized from an externally provided properties instance.

如何禁用第二个?

示例项目可以在这里找到: https://github.com/dajoropo/spring-quartz-demo/tree/stackoverflow_question_73459083

最简单的方法是使用 Spring 配置的调度程序,而不是自己做。 quartz.properties移动到application.properties中的spring.quartz命名空间。

spring.quartz.scheduler-name=MyQuartzScheduler

spring.quartz.properties.org.quartz.threadPool.threadCount=12
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true

spring.quartz.properties.org.quartz.jobStore.misfireThreshold=60000

要配置您自己的JobFactory ,请编写一个SchedulerFactoryBeanCustomizer以在SchedulerFactoryBean上进行配置。

@Component
class MySchedulerFactoryBeanCustomizer implements SchedulerFactoryBeanCustomizer {

  void customize(SchedulerFactoryBean schedulerFactoryBean) {
    schedulerFactoryBean.setJobFactory(new MyQuartzJobFactory());
  }
}

现在抛弃quartz.propertiesMyLifecycleListenerSchedulerManager并让 Spring 为您处理所有这些。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM