gpt4 book ai didi

spring-boot - 多飞路与 FlywayMigrationStrategy

转载 作者:行者123 更新时间:2023-12-02 00:04:35 30 4
gpt4 key购买 nike

我有多个 Flyway 数据源,需要为它们实现 FlywayMigrationStrategy。每个数据源都有自己的 flyway_migration 表等。

但是当我创建 FlywayMigrationStrategy 时,它不会被调用。

这行不通:

@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() { ...

这个有效:

  @PostConstruct
public void cleanBeforeMigrate(
@Qualifier("dpaFlyway") Flyway dpaflyway,
@Qualifier("flyway") Flyway flyway) {

dpaflyway.clean();
dpaflyway.migrate();

flyway.clean();
flyway.migrate();
}

有更好的选择吗?

最佳答案

为什么要实现@PostContruct方法?如我所见,FlywayMigrationStrategy 是一个函数式接口(interface),我想您的代码应该如下所示:

@Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
FlywayMigrationStrategy strategy = new FlywayMigrationStrategy() {
@Override
public void migrate(Flyway flyway) {
flyway.clean();
flyway.migrate();
}
};

return strategy;
}

好的,我做了一些研究,现在可以解释你问题的答案了。

首先,让我们检查一下FlywayAutoConfiguration

当您通过属性文件配置 flyway 迁移时,配置会起作用,创建和配置 Flyway 实例并迁移基础。所有这些都在 FlywayConfiguration 中配置。让我们看一下配置上的条件注释

@ConditionalOnMissingBean(Flyway.class)

这意味着如果类 Flyway.class 的 bean 已经存在于 spring 上下文中,则不会创建配置。 ok,接下来配置只创建到bean

@Bean
public Flyway flyway(FlywayProperties properties, DataSourceProperties dataSourceProperties,
ResourceLoader resourceLoader, ObjectProvider<DataSource> dataSource,
@FlywayDataSource ObjectProvider<DataSource> flywayDataSource,
ObjectProvider<FlywayConfigurationCustomizer> fluentConfigurationCustomizers,
ObjectProvider<JavaMigration> javaMigrations, ObjectProvider<Callback> callbacks)
.....
@Bean
@ConditionalOnMissingBean
public FlywayMigrationInitializer flywayInitializer(Flyway flyway,
ObjectProvider<FlywayMigrationStrategy> migrationStrategy) {
return new FlywayMigrationInitializer(flyway, migrationStrategy.getIfAvailable());
}

配置如何配置 flyway bean 并不重要,但重要的是它创建 FlywayMigrationInitializer,它会启动迁移。如您所见,FlywayMigrationStrategy 被设置为 FlywayMigrationInitializer 作为构造函数参数。如果设置了 MigrationStrategy,则由他使用,否则只需执行 flyway.migrate()。 (查看源代码)

好的,现在我们知道它的一般工作原理了,让我们看看您的代码。

您在主配置中创建飞路实例:

@Bean(initMethod = "migrate")
@FlywayDataSource
public Flyway firstFlyway(DataSource dataSource) {
return new Flyway(
new FluentConfiguration()
.locations("db/first-migration")
.schemas("first")
.outOfOrder(true)
.dataSource(dataSource)
);
}

@Bean(initMethod = "migrate")
@FlywayDataSource
public Flyway secondFlyway(@Qualifier("secondDataSource") DataSource dataSource) {
return new Flyway(
new FluentConfiguration()
.dataSource(dataSource)
.schemas("second")
.outOfOrder(true)
.locations("db/second-migration")
);
}

由于您已经创建了 Flyway 实例,因此未创建 FlywayConfiguration(由于条件)并且也未创建用于您的 Flyway bean 的 Initializer bean。因此,不会执行迁移,您需要将 (initMethod = "migrate") 添加到 bean 声明以开始迁移。另外,我认为 @FlywayDataSource 不是必需的,什么也不做。

现在让我们进入您的测试配置。

当您创建 FlywayMigrationStrategy 时,它可以正常工作,但没有人使用该策略(在您的主配置文件中调用 Flyway.migrate 就像 initMethod 和 MigrationInitializer 不是t 创建)。因此,该策略未执行。

在您的工作示例中,您在 TestConfiguration postconstruct 方法中添加了调用 clean 和 migrate。它之所以有效,是因为在创建配置后执行了 postconstruct 方法。 但是 如果你调试你的代码,你会看到 migrate 方法为每个 Flyway 实例执行了两次:作为 bean initMethod 和来自 Testconfiguration postcontruct方法。我不确定这是否是您想要的。

好的,为了修复它,我建议删除 (initMethod = "migrate")@FlywayDataSource,为每个 FlywayMigrationInitializer 创建 bean Flyway bean 在您的主要配置中,并在您的测试配置中实现 FlywayMigrationStrategy

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

关于spring-boot - 多飞路与 FlywayMigrationStrategy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61007862/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com