ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-在Spring Boot应用程序中使用默认和自定义liquibase配置

2019-10-26 20:02:12  阅读:613  来源: 互联网

标签:spring-boot liquibase spring java


我想在当前项目中使用Liquibase的两种配置.我想用于DDL更改的默认配置,第二个用于自定义插入的默认配置,其中changelog将位于另一个位置.

如果我配置SpringLiquibase,则由于LiquibaseAutoConfiguration类中的@ConditionalOnClass(SpringLiquibase.class)批注,将跳过默认的自动配置.
如何使用自定义的默认自动配置?我可以以某种方式覆盖@ConditionalOnClass注释吗?或者,也许有什么方法可以告诉Liquibase我在应用程序之外还有另一个changelog并仅在存在时运行它?

谢谢

编辑:

这可以解决我的问题,但是我在liquibase中加载外部文件(类路径之外的文件)时遇到问题.

@Configuration
@EnableConfigurationProperties(LiquibaseProperties.class)
public class LiquibaseConfiguration {

    @Bean
    SpringLiquibase liquibase(DataSource dataSource, LiquibaseProperties properties) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog(properties.getChangeLog());
        liquibase.setContexts(properties.getContexts());
        liquibase.setDataSource(dataSource);
        liquibase.setDefaultSchema(properties.getDefaultSchema());
        liquibase.setDropFirst(properties.isDropFirst());
        liquibase.setShouldRun(properties.isEnabled());
        liquibase.setLabels(properties.getLabels());
        liquibase.setChangeLogParameters(properties.getParameters());
        liquibase.setRollbackFile(properties.getRollbackFile());
        return liquibase;
    }

    @Bean
    SpringLiquibase commandInitializerLiquibase(DataSource dataSource,
            @Value("${docu.system.initializer.command.liquibase.changeLog}") String changeLogPath,
            @Value("${docu.system.initializer.command.liquibase.contexts}") String contexts) {
        File changeLog = new File(changeLogPath);
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setContexts(contexts);
        liquibase.setIgnoreClasspathPrefix(true);
        liquibase.setChangeLog(changeLog.getAbsolutePath());
        liquibase.setShouldRun(changeLog.exists());
        //liquibase.setResourceLoader(liquibaseResourceLoader());
        addPathToClassloader(changeLogPath);
        return liquibase;
    }
}

解决方法:

如果要使用Spring Boot自动配置的Liquibase功能,则上下文中只能有一个SpringLiquibase bean.
这是因为LiquibaseAutoConfiguration类中的@ConditionalOnMissingBean(SpringLiquibase.class)批注. Spring的条件功能将搜索SpringLiquibase实例及其子类实例,因此扩展SpringLiquibase类将无法解决该问题.

没有重写LiquibaseAutoConfiguration的好方法.
在这种情况下,您有3种解决方案可以解决您的问题:

1)实现两个单独的Liquibase bean配置:

@Configuration
public class LiquibaseConfiguration {

    @Autowired
    private DataSource dataSource;

    //define this property in your embedded properties file or use spring's default
    @Value("${liquibase.change-log}")
    private String defaultLiquibaseChangelog;

    @Bean
    public SpringLiquibase liquibase() {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog(defaultLiquibaseChangelog);
        // Configure rest of liquibase here...
        // ...
        return liquibase;
    }
}

@Configuration
public class LiquibaseConfiguration2 {

    @Autowired
    private DataSource dataSource;

    //optional, define it in external configuration or through command line param
    @Value("${liquibase.change-log-additional:#{null}}")
    private String additionalLiquibaseChangelog;

    @Bean(name = "additionalLiquibase")
    public SpringLiquibase liquibase() {
        if (additionalLiquibaseChangelog != null) {
            SpringLiquibase liquibase = new SpringLiquibase();
            liquibase.setDataSource(dataSource);
            liquibase.setChangeLog(additionalLiquibaseChangelog);
            // Configure rest of liquibase here...
            // ...
            return liquibase;
        }
        return null;
    }
}

2)对于手动配置的liquibase实例,使用Liquibase代替SpringLiquibase

使用一个自动配置的SpringLiquibase和一个纯Liquibase配置而不是SpringLiquibase(您将需要手动运行迁移并处理其他在SpringLiquibase中实现的工作)

3)仅使用一个SpringLiquibase实例

结合使用Liquibase的changelogParameters(http://www.liquibase.org/documentation/changelog_parameters.html),包含标签(http://www.liquibase.org/documentation/include.html)和仅一个SpringLiquibase实例.

示例实现:

Liquibase bean配置

@Configuration
public class LiquibaseConfiguration {

    @Autowired
    private DataSource dataSource;

    //define this property in your embedded properties file or use spring's default
    @Value("${liquibase.change-log}")
    private String defaultLiquibaseChangelog;

    //define this property in your embedded properties file
    @Value("${liquibase.extended-change-log}")
    private String extendedLiquibaseChangelog;

    //optional, define it in external configuration or through command line param
    @Value("${liquibase.data-change-log:#{null}}")
    private String liquibaseDataChangelog;

    @Bean
    public SpringLiquibase liquibase() {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        if (liquibaseDataChangelog != null) {
            //here you can check if file exists...
            Map<String, String> liquibaseChangelogParameters = new HashMap<>();
            liquibaseChangelogParameters.put("liquibaseExternalDataChangelogPath", liquibaseDataChangelog);
            liquibase.setChangeLog(extendedLiquibaseChangelog);
            liquibase.setChangeLogParameters(liquibaseChangelogParameters);
        } else {
            liquibase.setChangeLog(defaultLiquibaseChangelog);
        }
        // Configure rest of liquibase here...
        // ...
        return liquibase;
    }
}

changelog.xml(liquibase.change-log)

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">

    <include relativeToChangelogFile="true" file="changelog-master.xml"/>

</databaseChangeLog>

changelog-with-external-data.xml(liquibase.extended-change-log)

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">

    <include relativeToChangelogFile="true" file="changelog-master.xml"/>
    <include relativeToChangelogFile="false" file="${liquibaseDataChangelogPath}"/>

</databaseChangeLog>

请记住,拥有单独的变更日志可能很危险.您必须确保您的变更日志是独立的:

Included change-logs are run in the order they are found so care does
need to be taken to make sure that the included changelogs are either
completely independent, or that any required changelogs are run first.

标签:spring-boot,liquibase,spring,java
来源: https://codeday.me/bug/20191026/1939023.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有