0
votes

I am working on Spring MVC web application which is using JDBC Quartz Scheduler to execute jobs. This web application has multiple services each of which is packaged as an jar and has associated jobs. I have one quartz configuration which is in web project, under which I have created beans for jobs, triggers and scheduler. Under scheduler configuration, i specify a list of triggers. This was good when we started our project. As we started adding features, number of jobs increased and its now around 100+. It has become difficult to maintain this file. Is there any approach available make it modular so that the jobs/trigger/associating trigger to scheduler are not defined in the one single file.

 <bean name="incidentAutoClosure" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <property name="jobClass" value="itsm.scheduler.task.IncidentAutoClosureTask"/>
 </bean>
 <bean id="incidentAutoClosureTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail" ref="incidentAutoClosure" />
    <property name="cronExpression" value="0 0 12 1/1 * ? *" />
 </bean>
 <bean id="quartzJdbcScheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
    p:waitForJobsToCompleteOnShutdown="true">
    <property name="autoStartup" value="true" />
    <property name="startupDelay" value="0" />
    <property name="overwriteExistingJobs" value="false" />
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.scheduler.instanceName">mvcJdbcScheduler</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.PostgreSQLDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">${quartz.async.threadCount}</prop>
            <prop key="org.quartz.threadPool.threadPriority">${quartz.async.threadPriority}</prop>
            <prop key="org.quartz.jobStore.misfireThreshold">${quartz.async.misfireThreshold}</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer">true</prop>
                <prop key="org.quartz.plugin.jobHistory.class">org.quartz.plugins.history.LoggingJobHistoryPlugin</prop>
                <prop key="org.quartz.plugin.jobHistory.jobToBeFiredMessage">${quartz.async.initTriggerFormat}</prop>
                <prop key="org.quartz.plugin.jobHistory.jobSuccessMessage">${quartz.async.endTriggerFormat}</prop>
        </props>
    </property>
     <property name="triggers">
        <list>
                <ref bean="incidentAutoClosureTrigger" />
                <!-- List of 100 Jobs -->
        </list>
    </property>
</bean>
2

2 Answers

0
votes

Few things, Are you using spring boot? A good approach to this problem would be to create auto configuration class where you can have a list of combinations. Here is a sample:

@Configuration
@ConditionalOnBean(SomeClassDependency.class)
public class JobConfig {

    @Bean
    @ConditionalOnProperty(....)
    public SchedulerFactoryBean config1() {
        ....
    }

    @Bean
    @ConditionalOnProperty(....)
    public SchedulerFactoryBean config2() {
        ....
    }

    @Bean
    @ConditionalOnProperty(....)
    public SchedulerFactoryBean config3() {
        ....
    }
}

public class MyDependency {

    private final SchedulerFactoryBean schedulerFactoryBean;

    public MyDependency(@Qualifier("config2") SchedulerFactoryBean schedulerFactoryBean) {
        this.schedulerFactoryBean = schedulerFactoryBean
    }
}
0
votes

you can do it programmatically through a configuration class that will automatically configure your bean instead of using an xml file;

here is what I used. Note: having the applicationContext added to the jobFactory allows Quartz schedule jobs to be aware of spring autowired classes when the job executes otherwise you'll get a null autowire

@Configuration
public class PortalQuartzSchedulerConfiguration {

  @Autowired
  private ApplicationContext applicationContext;

  @Bean
  public JobFactory jobFactory() {
    ApplicationContextHolder jobFactory = new ApplicationContextHolder();
    jobFactory.setApplicationContext(applicationContext);
    return jobFactory;
  }

  @Bean
  public SchedulerFactoryBean schedulerFactory() {
    SchedulerFactoryBean factory = new SchedulerFactoryBean();
    factory.setAutoStartup(true);
    factory.setSchedulerName("Portal scheduler");
    factory.setOverwriteExistingJobs(true);
    factory.setJobFactory(jobFactory());
    return factory;
  }

}