You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让SpringBoot主项目执行外部Liquibase库与自身的迁移脚本?

解决方案

方案一:注册多个Liquibase Bean(独立执行两个变更日志)

这种方式会创建两个Liquibase实例,分别处理库和主项目的变更日志,自动继承主项目的所有Liquibase配置(数据源、上下文、参数等)。

  1. 将公共库改造为Spring Boot Starter
    在库的src/main/resources/META-INF/spring/目录下创建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,添加自动配置类的全限定名:

    com.your.library.config.LibraryLiquibaseAutoConfiguration
    
  2. 编写自动配置类
    创建LibraryLiquibaseAutoConfiguration类,注册两个SpringLiquibase Bean:

    import liquibase.integration.spring.SpringLiquibase;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.sql.DataSource;
    
    @Configuration
    @ConditionalOnClass(SpringLiquibase.class)
    @EnableConfigurationProperties(LiquibaseProperties.class)
    public class LibraryLiquibaseAutoConfiguration {
    
        private final LiquibaseProperties properties;
    
        public LibraryLiquibaseAutoConfiguration(LiquibaseProperties properties) {
            this.properties = properties;
        }
    
        // 执行库的变更日志
        @Bean
        public SpringLiquibase libraryLiquibase(DataSource dataSource) {
            SpringLiquibase liquibase = new SpringLiquibase();
            liquibase.setDataSource(dataSource);
            liquibase.setChangeLog("classpath:library.xml");
            // 复用主项目的Liquibase配置
            liquibase.setContexts(properties.getContexts());
            liquibase.setDefaultSchema(properties.getDefaultSchema());
            liquibase.setDropFirst(properties.isDropFirst());
            liquibase.setShouldRun(properties.isEnabled());
            liquibase.setLabels(properties.getLabels());
            liquibase.setChangeLogParameters(properties.getParameters());
            return liquibase;
        }
    
        // 执行主项目的变更日志
        @Bean
        public SpringLiquibase mainLiquibase(DataSource dataSource) {
            SpringLiquibase liquibase = new SpringLiquibase();
            liquibase.setDataSource(dataSource);
            liquibase.setChangeLog(properties.getChangeLog());
            // 复用主项目的Liquibase配置
            liquibase.setContexts(properties.getContexts());
            liquibase.setDefaultSchema(properties.getDefaultSchema());
            liquibase.setDropFirst(properties.isDropFirst());
            liquibase.setShouldRun(properties.isEnabled());
            liquibase.setLabels(properties.getLabels());
            liquibase.setChangeLogParameters(properties.getParameters());
            return liquibase;
        }
    }
    

方案二:使用组合变更日志(单Liquibase实例执行两个文件)

这种方式通过一个组合的变更日志文件,先引入库的变更日志,再引入主项目的变更日志,只需一个Liquibase实例,执行顺序更可控。

  1. 创建组合变更日志文件
    在库的src/main/resources下创建combined-changelog.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <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-4.9.xsd">
    
        <!-- 优先执行库的变更日志 -->
        <include file="library.xml" relativeToChangelogFile="true"/>
        <!-- 再执行主项目配置的变更日志 -->
        <include file="${spring.liquibase.change-log}" relativeToChangelogFile="false"/>
    
    </databaseChangeLog>
    
  2. 编写自动配置类覆盖变更日志配置
    创建自动配置类,将主项目的变更日志路径作为参数传入,替换默认的change-log为组合文件:

    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    
    import javax.annotation.PostConstruct;
    
    @Configuration
    @ConditionalOnClass(name = "liquibase.integration.spring.SpringLiquibase")
    @EnableConfigurationProperties(LiquibaseProperties.class)
    public class LibraryLiquibaseAutoConfiguration {
    
        private final LiquibaseProperties liquibaseProperties;
        private final Environment environment;
    
        public LibraryLiquibaseAutoConfiguration(LiquibaseProperties liquibaseProperties, Environment environment) {
            this.liquibaseProperties = liquibaseProperties;
            this.environment = environment;
        }
    
        @PostConstruct
        public void setupCombinedChangeLog() {
            // 获取主项目原本配置的变更日志路径,默认值适配主项目的main.xml
            String originalChangeLog = environment.getProperty("spring.liquibase.change-log", "main.xml");
            // 设置组合变更日志为默认执行文件
            liquibaseProperties.setChangeLog("classpath:combined-changelog.xml");
            // 将主项目的变更日志路径传入作为参数
            liquibaseProperties.getParameters().put("spring.liquibase.change-log", originalChangeLog);
        }
    }
    
  3. 配置Starter自动扫描
    同样在org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中添加上述配置类的全限定名,确保主项目引入后自动加载。

注意事项

  • 两种方案都要求公共库是Spring Boot Starter,否则主项目无法自动加载库中的配置类。
  • 方案二中,如果主项目的变更日志不是classpath下的文件,需要确保include标签能正确定位(比如使用绝对路径或合适的资源前缀)。
  • 执行顺序:方案一的两个Liquibase Bean执行顺序由Spring的Bean加载顺序决定;方案二则严格按照组合日志中的include顺序执行(先库后主项目)。

内容的提问来源于stack exchange,提问作者Mihai Catalin Valentin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:20:20