java - Flyway的Java迁移文件中使用JdbcTemplate导致依赖循环

标签 java spring-boot flyway

从版本 6.* 开始,Flyway 支持将 Spring bean 注入(inject)到实现了 JavaMigration 接口(interface)的 java 迁移文件中。这是我的例子:

@Component
public class V1_201809261821__some_migration extends BaseJavaMigration {

    @Autowired
    private SomeDAO someDAO;

    @Override
    public void migrate(Context context) throws Exception {
        someDAO.doSomething();
    }
}

启动时,它会提示:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   v1_201809261821__some_migration (field private SomeDAO V1_201809261821__some_migration.someDAO)
┌─────┐
|  someDAO (field private org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate someDAO.namedParameterJdbcTemplate)
↑     ↓
|  flywayInitializer defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]
↑     ↓
|  flyway defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]
↑     ↓
|  v1_201809261821__some_migration (field private SomeDAO V1_201809261821__some_migration.someDAO)
└─────┘

看来我无法在Java迁移文件中使用JdbcTemplateFlyway's document表明我可以使用 Context 构建自己的 JdbcTemplate,如下所示:

public void migrate(Context context) {
        new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true))
                .execute("INSERT INTO test_user (name) VALUES ('Obelix')");
}

但不幸的是我无法控制 SomeDAO,它来自另一个我无法触及的模块。

相关版本:

  • 飞行路线:6.0.6

  • Spring Boot:2.2.0

最佳答案

这就是 Spring Boot 决定集成 Flyway 的方式。 在默认的自动配置中,在 Flyway 迁移完成之前,您无法对数据库执行任何操作。这是一个明智但固执己见的选择。

看一下FlywayAutoConfiguration的源码。有一个相当令人讨厌的技巧来确保在 Flyway 准备好之前没有人可以使用 JdbcTemplate:

        /**
         * Additional configuration to ensure that {@link JdbcOperations} beans depend on
         * the {@code flywayInitializer} bean.
         */
        @Configuration
        @ConditionalOnClass(JdbcOperations.class)
        @ConditionalOnBean(JdbcOperations.class)
        protected static class FlywayInitializerJdbcOperationsDependencyConfiguration
                extends JdbcOperationsDependsOnPostProcessor {

            public FlywayInitializerJdbcOperationsDependencyConfiguration() {
                super("flywayInitializer");
            }

        }

为了实现您的目标,您必须禁用此自动配置(spring.autoconfigure.exclude)并自己编写 Flyway 配置。您可以从 FlywayAutoConfiguration 的源代码开始,但删除了棘手的方法。

但是,您必须添加类似的依赖技巧,以确保您的服务/作业仅在您的自定义 Flyway 准备就绪后启动。

关于java - Flyway的Java迁移文件中使用JdbcTemplate导致依赖循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58498265/

相关文章:

spring-boot - Flyway 6 JavaMigrations 与 Spring Beans 的 native 依赖注入(inject)

java - 如何计算BitSet对象中的总位数?

Spring Boot Localhost https 问题

spring - Intellij 问题解决了 spring kotlin 的依赖关系

Spring Boot Camel Route - 从休息端点获取数据

spring-boot - Spring 启动 : Flyway migration before mybatis initialization

java - Flyway 仅迁移我的两个配置模式之一

java - 在 Redis 中使用引号存储值

java - hibernate 如何访问私有(private)字段?

java - 如何在 Selenium 2 中选择/获取下拉选项