首页 > 解决方案 > How to access Spring Boot Quartz Bean from another module?

问题描述

I have a Spring Boot project that is going to be using Quartz to manage the running of some scripts. The project layout is as follows:

scheduler
|
|__scheduler-api
|  |
|  |__quartz-bean
|
|__scheduler-composition
   |
   |__service-to-schedule-quartz-jobs-using-quartz-bean

The api module is a Spring Boot application where the quartz bean lives. The composition module is where my services live that will be used to add jobs and triggers to Quartz. The problem I am running into is that my Quartz bean is not accessible from the composition module, therefore I am not able to schedule jobs in my service like I'd want to. My Quartz bean is defined as follows:

@Configuration
class QuartzScheduler {
    @Autowired
    private val applicationContext: ApplicationContext? = null

    @Autowired
    private val databaseConfiguration: DatabaseConfiguration? = null

    @Bean
    fun springBeanJobFactory(): SpringBeanJobFactory {
        val jobFactory = AutoWiringSpringBeanJobFactory()
        jobFactory.setApplicationContext(applicationContext!!)
        return jobFactory
    }

    @Bean
    @Throws(SchedulerException::class)
    fun scheduler(@Qualifier("schedulerFactoryBean") factory: SchedulerFactoryBean): Scheduler {
        val scheduler = factory.scheduler   
        scheduler.start()
        return scheduler
    }

    @Bean
    @Throws(IOException::class)
    fun schedulerFactoryBean(): SchedulerFactoryBean {
        val factory = SchedulerFactoryBean()
        factory.setDataSource(databaseConfiguration!!.dataSource())
        factory.setJobFactory(springBeanJobFactory())
        factory.setQuartzProperties(quartzProperties())
        return factory
    }

    @Throws(IOException::class)
    fun quartzProperties(): Properties {
        val propertiesFactoryBean = PropertiesFactoryBean()
        propertiesFactoryBean.setLocation(ClassPathResource("/quartz.properties"))
        propertiesFactoryBean.afterPropertiesSet()
        return propertiesFactoryBean.getObject()!!
    }
}

A couple things I've tried include moving the Quarts bean to the composition module, but then it doesn't have access to the database configuration it needs. I also tried importing the api module into the composition module but it created a circular dependency. Can someone help me access the Quartz bean from my composition module? I'm new to Spring Boot so I am not really sure where I am going wrong or what my options are even. Thanks!

Edit

My service looks like this:

class QuartzService {

    @Autowired
    private var quartzScheduler: QuartzScheduler? = null

    fun upsertJob(job: JobEntity) {
        var jobExists = quartzScheduler!!.scheduler().checkExists(JobKey.jobKey(job.id.toString()))
        if (!jobExists) {
            quartzScheduler!!.scheduler().addJob(
                    newJob().ofType(EnqueueJob::class.java).storeDurably().withIdentity(JobKey.jobKey(job.id.toString())).build(),
                    true
            )
        }
    }
}

The error that appears is that the type QuartzScheduler cannot be found (my QuartzScheduler class from scheduler-api)

标签: javaspring-bootkotlinspring-data-jpaquartz-scheduler

解决方案


我遇到了几个问题。首先,我的 Quartz 服务不正确地自动连接调度程序。我把它改成这样:

class QuartzService {

    @Autowired
    private lateint var scheduler: Scheduler

    fun upsertJob(job: JobEntity) {
        var jobExists = scheduler.checkExists(JobKey.jobKey(job.id.toString()))
        if (!jobExists) {
            scheduler.addJob(
                    newJob().ofType(EnqueueJob::class.java).storeDurably().withIdentity(JobKey.jobKey(job.id.toString())).build(),
                    true
            )
        }
    }
}

接下来,我不得不更改使用 Quartz 服务的类来自动连接服务,我不小心将它实例化为普通对象:

@Autowired
private lateinit var quartzService: QuartzService

感谢大家的帮助!


推荐阅读