Как использовать Flyway в проекте Grails 3 с автоконфигурацией Spring Boot

В соответствии с документацией по Flyway можно использовать Flyway в проекте Grails 3 за пределами -коробка:

Grails 3.x основан на Spring Boot и поставляется с готовой интеграцией для Flyway.
Все, что вам нужно сделать, это добавить flyway-core в ваш build.gradle:
compile "org.flywaydb:flyway-core:4.1.1"
Spring Boot затем автоматически подключит Flyway к своему источнику данных и вызовет его при запуске.

Это не работает для меня. Flyway не срабатывает при запуске приложения. В логах вижу подозрительные строчки:

   FlywayAutoConfiguration did not match
      - @ConditionalOnClass found required class 'org.flywaydb.core.Flyway' (OnClassCondition)
      - @ConditionalOnProperty (flyway.enabled) matched (OnPropertyCondition)
      - @ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans (OnBeanCondition)
...
Exclusions:
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

А вот как выглядит класс Spring FlywayAutoConfiguration:

@Configuration
@ConditionalOnClass(Flyway.class)
@ConditionalOnBean(DataSource.class)
@ConditionalOnProperty(prefix = "flyway", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class })
public class FlywayAutoConfiguration {

Так что мне кажется, что это не работает, потому что DataSourceAutoConfiguration исключен из автонастройки.

Верен ли этот анализ?

Почему и где исключено DataSourceAutoConfiguration? Предположительно где-то глубоко внутри Grails, потому что я не знаю ни одного места в моем коде, которое могло бы вызвать это.

Как сделать так, чтобы интеграция flyway в Grails работала так, как обещано документацией Flyway? Я знаю, что могу сделать это вручную через resources.groovy (рабочий код из моего проекта, сильно вдохновленный код подключаемого модуля Grails Flyway):

if (application.config.flyway.enabled != false) {
    flyway(Flyway) { bean ->
        bean.initMethod = 'migrate'
        dataSource = ref('dataSource')
        baselineOnMigrate = application.config.flyway.baselineOnMigrate
    }

    BeanDefinition sessionFactoryBeanDef = getBeanDefinition('sessionFactory')

    if (sessionFactoryBeanDef) {
        def dependsOnList = ['flyway'] as Set
        if (sessionFactoryBeanDef.dependsOn?.length > 0) {
            dependsOnList.addAll(sessionFactoryBeanDef.dependsOn)
        }
        sessionFactoryBeanDef.dependsOn = dependsOnList as String[]
    }
}

но, если возможно, я бы предпочел подход с автоматической настройкой, потому что он поддерживает многие свойства пролетного пути «из коробки», и я могу поддерживать порядок в своих ресурсах.


person Matthias    schedule 22.02.2017    source источник
comment
stackoverflow.com/a/43214863   -  person zyro    schedule 13.07.2017