簡體   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-2025 STACKOOM.COM