【问题标题】:How to access Spring Boot Quartz Bean from another module?如何从另一个模块访问 Spring Boot Quartz Bean?
【发布时间】:2020-08-15 23:48:04
【问题描述】:

我有一个 Spring Boot 项目,它将使用 Quartz 来管理一些脚本的运行。项目布局如下:

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

api 模块是石英 bean 所在的 Spring Boot 应用程序。组合模块是我的服务所在的地方,它将用于向 Quartz 添加作业和触发器。我遇到的问题是我的 Quartz bean 无法从组合模块访问,因此我无法像我想要的那样在我的服务中安排作业。我的 Quartz bean 定义如下:

@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()!!
    }
}

我尝试过的一些事情包括将 Quarts bean 移动到组合模块,但是它无法访问所需的数据库配置。我还尝试将 api 模块导入组合模块,但它创建了一个循环依赖项。有人可以帮我从我的合成模块中访问 Quartz bean 吗?我是 Spring Boot 的新手,所以我不确定我哪里出错了,或者我的选择是什么。谢谢!

编辑

我的服务如下所示:

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
            )
        }
    }
}

出现的错误是找不到类型QuartzScheduler(我的QuartzScheduler类来自scheduler-api

【问题讨论】:

  • 你在使用 Maven/Gradle 吗?如果是这样,您是否表达了scheduler-composition 模块和scheduler-api 模块之间的依赖关系?
  • @user2340612 我正在使用 Gradle。我将依赖项添加到scheduler-composition,但它创建了一个循环引用,因为scheduler-api 也依赖于scheduler-composition。我在这里不走运吗?
  • 对不起,我提出了错误的建议,那是编译时依赖,而不是运行时依赖。所以在运行时你的scheduler bean 应该是可见的,只要两个模块作为同一个 Spring Boot 应用程序的一部分运行。你得到什么样的例外?
  • @user2340612 当我尝试@Autowired Quartz 服务中的 bean 时,类型无法识别。它不会编译。也许我误解了如何使用 Quartz bean?
  • 如果它没有编译,那么你的 Gradle 依赖项有问题。错误在哪里?如果它在 @Autowired 上,那么您缺少 spring 依赖项,而如果是 Scheduler,那么您缺少 Quartz 依赖项

标签: java spring-boot kotlin spring-data-jpa quartz-scheduler


【解决方案1】:

我遇到了几个问题。首先,我的 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

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2016-08-19
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多