Spring - 在初始化其他内容之前检查应用程序启动时的配置属性

问题描述 投票:0回答:1

我想在初始化其他内容之前执行一个函数来检查数据库配置。但是,无论我使用什么方法,它总是在其他一些组件或服务之后被调用,这并不理想。是否可以将其全局优先级设置为上下文初始化后创建的第一个组件?

我已经尝试了以下方法,下面的实现最接近我想要的,但仍然不完全——因为它是在 Flyway 数据库执行器之后执行的:

@Configuration
class DataSourceConfig(
    @Value("\${spring.datasource.url}") private val databaseUrl: String
) {
    init {
        if (databaseUrl.lowercase().contains("jdbc:sqlite:", ignoreCase = true)) {
            err.println("!!! ERROR !!!\n" +
                "SQLite isn't supported in the v1 development branch yet.\n" +
                "Please either switch to MariaDB or wait for the stable v1 release.\n")
            exitProcess(1)
        }
    }
}

以下是我尝试过的其他选项:

  1. @PostConstruct
    ,与以下选项同时执行:
@Configuration
class DataSourceConfig(
    private val dataSource: DataSource
) {
    @PostConstruct
    fun checkDataSource() {
        val databaseUrl = JdbcUtils.extractDatabaseMetaData(dataSource) { it.url }
        // ...
    }
}
  1. 添加
    @EventListener(ApplicationReadyEvent::class)
    。当其他所有内容都初始化时,它会在最近执行,这不是我想要的。
@Configuration
class DataSourceConfig(
    @Value("\${spring.datasource.url}") private val databaseUrl: String
) {
    @EventListener(ApplicationReadyEvent::class)
    fun checkDataSource() {
        // ...
    }
}
  1. 使用

    @EventListener(ContextRefreshedEvent::class)
    。在我的测试中,这个事件根本没有被调用,并且应用程序在没有调用检查的情况下启动,这导致了一个非常令人困惑的错误消息。

  2. 使用

    CommandLineRunner
    bean,当一切都已经初始化时仍在执行。

@Configuration
class DataSourceConfig {
    @Bean
    fun checkDataSource(dataSource: DataSource) = CommandLineRunner {
        val databaseUrl = JdbcUtils.extractDatabaseMetaData(dataSource) { it.url }

        // ...
    }
}
java spring hibernate kotlin flyway
1个回答
1
投票

根据文档

org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent
事件可能符合您的要求。一旦环境可用,它就会被触发,您可以使用
getEnvironment()
事件的方法访问它。

注意,由于此事件是在这么早的阶段触发的,因此您将无法使用

@EventListener
带注释的方法捕获它。您需要实现
ApplicationListener<ApplicationEnvironmentPreparedEvent>
接口并在 main 方法中手动注册它。像这样的东西

public static void main(String[] args) {
    SpringApplication springApplication = new SpringApplication(App.class);
    springApplication.addListeners((ApplicationListener<ApplicationEnvironmentPreparedEvent>) event -> {
        ConfigurableEnvironment environment = event.getEnvironment();
        //check or modify environment here
    });
    springApplication.run(args);
}
© www.soinside.com 2019 - 2024. All rights reserved.