首页 > 解决方案 > 带有配置的 Spring 初始化顺序

问题描述

我有一个Spring项目,我需要配置Flyway。使用默认的 FlywayAutoConfiguration,Flyway 迁移在其他一切(缓存、PostConstruct 注释、服务)之前立即执行。这是我预期的行为(在术语或启动工作流程中)

不幸的是,我需要覆盖默认的 FlywayAutoConfiguration,因为我使用自定义 Flyway 实现,但这不是我的主要问题,我的问题实际上与配置和初始化序列的 Spring Priority 有关。

所以请使用我自己的 flyway,我首先将 FlywayAutoConfiguration 复制到我的 maven 模块中,将其命名为 CustomFlywayAutoConfiguration 并调整导入。我还将属性“spring.flyway.enabled”更改为 false 并创建另一个“spring.flywaycustom.enabled”,以便能够激活我的而不是默认的。

这样做会完全改变启动顺序。现在,flyway 在启动序列结束时执行(在缓存和我项目中的其他 @PostConstruct 之后)

CustomFlywayAutoConfiguration 中定义的以下 bean 现在仅在启动序列结束时创建。使用默认的 FlywayAutoConfiguration ,一开始就很好地创建了。

@Bean
    @ConditionalOnMissingBean
    public FlywayMigrationInitializer flywayInitializer(Flyway flyway,
            ObjectProvider<FlywayMigrationStrategy> migrationStrategy) {
        return new FlywayMigrationInitializer(flyway, migrationStrategy.getIfAvailable());
    }

我试着玩了很多订购(HIGHEST_PRECEDENCE 和 LOWEST_PRECEDENCE)

它没有改变任何东西,看起来像 Spring 忽略 @Order 和 @AutoConfigureOrder

知道为什么当配置在 spring-boot-autoconfigure 依赖项中时,它作为第一优先级启动,而当相同的配置代码在我的项目中时,我没有相同的顺序?

非常感谢你的帮助。

标签: javaspringspring-bootspring-context

解决方案


您描述的所有注释都不会影响运行时语义:

  • @AutoConfigureOrder仅适用于自动配置(因此,如果您已将自动配置复制为用户配置,则甚至不会考虑)。这用于订购如何解析自动配置(典型用例:确保自动配置在另一个检查 bean X 是否可用之前贡献类型 X 的 bean 定义)。
  • @Order订购相同类型的组件。对“何时”发生某事没有任何影响

使用注入点强制初始化是一个好主意,但它只有在您注入它的组件在正确的时间自行初始化时才会起作用。

自动配置有一堆后处理器,它们在使用DataSourceFlywayMigrationInitializer. 例如,FlywayMigrationInitializerEntityManagerFactoryDependsOnPostProcessor确保它FlywayMigrationIntializer是实体管理器的依赖项,以便在EntityManager其他组件可用之前迁移数据库。该链接确保 Flyway 在正确的时间执行。我不知道为什么这不适用于您的副本,我们可以自己运行的示例在 GitHub 上共享可以帮助我们弄清楚。

尽管如此,请不要在您自己的项目中复制自动配置。我建议更详细地描述您的用例并打开一个问题,以便我们考虑改进自动配置。


推荐阅读