使用 Spring Boot 运行基于 Java 的 Flyway 回调

Posted

技术标签:

【中文标题】使用 Spring Boot 运行基于 Java 的 Flyway 回调【英文标题】:Run Flyway Java-based callbacks with Spring Boot 【发布时间】:2016-10-13 07:48:12 【问题描述】:

有没有办法用 Spring boot 运行Flyway Java-based callbacks? 我正在转换一个现有项目,每次迁移后都会更新一些视图定义,这是由 Java 完成的,因为它需要一些额外的逻辑。我知道它可以在 pl/pgsql 中完成(我们正在使用 Postgres),但它已经在 J​​ava 中完成并测试了。

Spring boot docs 说这是可能的,但它列出了回调脚本应该与迁移位于同一目录中,也许这仅适用于基于 SQL 的回调。

此代码无需 Spring Boot 即可工作:

    Flyway flyway = new Flyway();
    flyway.setDataSource(this.getDataSource());
    flyway.setLocations("/db/migration");
    flyway.setCallbacks(new LogMaintenanceFlywayCallback());
    flyway.migrate();

我在/db/migration 中进行了多次迁移,每次迁移后我都需要执行回调。它适用于我当前的项目,我需要在 Spring Boot 中执行相同的操作(或以其他方式获得相同的行为)。

【问题讨论】:

它有效。您需要将您的 Java 类放在 db.migrations 包中。 它们必须在标准中命名吗?我创建了一个SomeMaintenanceFlywayCallback,实现了接口FlywayCallback,并且没有调用方法afterEachMigrate。我试图将课程重命名为AfterEachMigrate,但也没有成功。它在db.migrations 包中,与执行的Java 迁移并排,所以构建路径没问题。 SQL 迁移应该在src/main/resources/db/migration 中。 Java 迁移应该在src/main/java/db/migration 中。每个文件通常以Vxxx__some-text-here.sql 或 Vxxx__MyJavaClass.java` 开头。 刚看到我的第一条评论是错误的。不是db.migrations,而是db.migration。见docs.spring.io/spring-boot/docs/current/reference/html/… 我也写错了,已经在db.migration了。正如我所说,我的迁移正在执行,我需要的是回调,在每次迁移后运行一些代码。我已经更新了我的问题,以包含使用 Flyway 的手动方式。 【参考方案1】:

你可以有这样的配置,它会工作:

@Configuration
public class FlywayFactory 

    @Bean
    public FlywayMigrationInitializer flywayInitializer(Flyway flyway, FlywayCallback flywayCallback) 
        flyway.setCallbacks(flywayCallback);
        return new FlywayMigrationInitializer(flyway);
    

    @Bean
    public FlywayCallback flywayCallback() 
        return new LogMaintenanceFlywayCallback();
    

【讨论】:

理论上解决方案是正确的,但以下答案更适合解决实际问题。我经历了 FlywayMigrationStrategy 的方法 你不应该直接调用bean方法。要么注入回调,要么使回调类不是 bean。【参考方案2】:

似乎无法在 Spring Boot 自动配置中设置回调(参见 FlywayAutoConfiguration.java)

你可以做两件事:

    在您的Configuration 类之一中创建您自己的Flyway 实例。如果您这样做,Spring Boot 不会创建他的实例。 在Configuration 类之一中自动装配Flyway 实例,并在PostConstruct 方法中调用setCallbacks 方法(但确保在迁移开始之前调用setter 可能会很棘手)李>

【讨论】:

【参考方案3】:

由于 Flyway 的方法 setCallbacks(Callback... callbacks) 已被弃用并将在 Flyway 6.0 中删除,您可以使用新的 API 和 FlywayConfigurationCustomizer 来设置自定义的基于 Java 的回调。那么配置如下:

@Configuration
public class FlywayFactory 

    @Bean
    public FlywayConfigurationCustomizer flywayConfigurationCustomizer() 
        return configuration -> configuration.callbacks(new LogMaintenanceFlywayCallback());
    

【讨论】:

【参考方案4】:

您可以覆盖 Flyway 迁移策略

@Component
public class CallbackFlywayMigrationStrategy implements FlywayMigrationStrategy 

    @Override
    public void migrate(Flyway flyway) 
        flyway.setCallbacks(new LogMaintenanceFlywayCallback());
        flyway.migrate();
    


【讨论】:

【参考方案5】:

你可以定义一个org.flywaydb.core.api.callback.Callback类型的bean,如下:

@Bean
public Callback logMaintenanceFlywayCallback() 
    return new LogMaintenanceFlywayCallback();

【讨论】:

以上是关于使用 Spring Boot 运行基于 Java 的 Flyway 回调的主要内容,如果未能解决你的问题,请参考以下文章

在 GCP 上运行基于 Java 的 API 后端(Spring Boot、Micronaut、Quarkus)最经济有效的方法是啥?

spring boot 使用脚本启动.bat怎么写

spring boot 怎么启动

Spring Boot学习之一Spring Boot简介

Spring Boot基础

如何获取spring boot application.yml里面的值