search
  • Sign In
  • Sign Up
Password reset successful

Follow the proiects vou are interested in andi aet the latestnews about them taster

Table of Contents
1. Introduction: Multi-module Liquibase integration challenges
2. Core idea: Define multiple SpringLiquibase Beans
3. Option 1: Simple multi-Liquibase configuration based on @Configuration
3.1 Configuration example
4.3 Precautions
4. Option 2: Use @ConfigurationProperties for advanced multi-Liquibase configuration
4.1 Property configuration (application.properties)
4.2 Java configuration class
5. Summary and best practices
Home Java javaTutorial Spring Boot integrates external library Liquibase multiple Changelog management tutorial

Spring Boot integrates external library Liquibase multiple Changelog management tutorial

Dec 31, 2025 am 08:12 AM

Spring Boot integrates external library Liquibase multiple Changelog management tutorial

This tutorial details how to manage the Liquibase database migration of both the main project and external libraries in a Spring Boot application. The core method is to configure different changeLog files by defining multiple SpringLiquibase Beans. The article provides two implementation options: one is based on direct bean definition of @Configuration, and the other is to use @ConfigurationProperties for more flexible property binding, and discusses key considerations such as code examples, configuration details, and execution order, aiming to help developers effectively solve multi-module Liquibase integration problems.

1. Introduction: Multi-module Liquibase integration challenges

In a Spring Boot project, when the main application needs to introduce an external shared library (such as a JAR package), if the external library also uses Liquibase for database version management and has its own changelog file (such as library.

Spring Boot's Liquibase auto-configuration usually only loads a main changelog based on the spring.liquibase.change-log property. In order to solve this problem, we need to define multiple SpringLiquibase instances through custom configuration, each instance is responsible for managing a specific changelog file.

2. Core idea: Define multiple SpringLiquibase Beans

Liquibase is integrated in Spring Boot through the SpringLiquibase class. By default, Spring Boot automatically configures a SpringLiquibase Bean. To manage multiple changelog files, the most straightforward way is to manually define additional SpringLiquibase Beans. Each Bean can independently configure its data source and changelog path.

Two implementation methods will be introduced below.

3. Option 1: Simple multi-Liquibase configuration based on @Configuration

This approach manages different changelogs by manually creating and configuring SpringLiquibase Beans in a configuration class. It is suitable for scenarios that require clear control over configuration and do not want to rely too much on Spring Boot's automatic configuration property binding.

3.1 Configuration example

Create a Spring @Configuration class and define multiple SpringLiquibase beans in it:

 package com.example.app.config;

import liquibase.integration.spring.SpringLiquibase;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.sql.DataSource;

@Configuration // Ensure that this configuration class is scanned by Spring public class MultipleLiquibaseConfiguration {

    /**
     * Configure the Liquibase instance of the external library * Responsible for performing migrations in library.xml * @param dataSource The data source of the application * @return The configured SpringLiquibase instance */
    @Bean
    public SpringLiquibase liquibaseLib(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog("classpath:library.xml"); // Specify the changelog file of the library // You can set other properties as needed, such as default mode, context, etc. // liquibase.setDefaultSchema("lib_schema");
        return liquibase;
    }

    /**
     * Configure the Liquibase instance of the main application * Responsible for executing migrations in main.xml * @param dataSource The data source of the application * @return The configured SpringLiquibase instance */
    @Bean
    @DependsOn("liquibaseLib") // If the migration of the main application depends on the migration of the library, use @DependsOn
    public SpringLiquibase liquibaseMain(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog("classpath:main.xml"); // Specify the changelog file of the main application // You can set other properties as needed return liquibase;
    }
}

3.2 Precautions

  • @Configuration : Make sure your configuration class is scanned by the Spring Boot application.
  • DataSource : Both SpringLiquibase beans are injected with the same DataSource, which means they will perform migrations on the same database. If you need to perform migrations on different databases or different schemas, you need to inject or create different DataSource instances.
  • changeLog path : Use the classpath: prefix to ensure that Liquibase can find the changelog file from the classpath. library.xml should be located in the src/main/resources directory of the external library, and main.xml should be located in the src/main/resources directory of the main application.
  • Execution order : If the database migration of the external library must be performed before the migration of the main application (for example, the tables of the main application depend on tables created by the external library), you can use the @DependsOn("liquibaseLib") annotation to force the liquibaseMain Bean to be initialized after the liquibaseLib Bean.

4. Option 2: Use @ConfigurationProperties for advanced multi-Liquibase configuration

This solution is more flexible and allows you to configure the properties of multiple Liquibase instances through application.properties or application.yml files, similar to Spring Boot's automatic configuration of the default Liquibase. This is useful when you need to externalize configuration or have multiple modules that need to configure Liquibase independently.

4.1 Property configuration (application.properties)

In application.properties of the main project, define independent property prefixes for each Liquibase instance:

 # Liquibase configuration for the main application (usually automatically configured by spring.liquibase)
spring.liquibase.change-log=classpath:/main.xml
spring.liquibase.enabled=true
# ... Other spring.liquibase.* properties # Liquibase configuration for external libraries, use custom prefix 'lib.liquibase'
lib.liquibase.change-log=classpath:/library.xml
lib.liquibase.enabled=true
# ...other lib.liquibase.* properties

4.2 Java configuration class

In the startup class of the main application or a configuration class, manually create a SpringLiquibase Bean and bind it to the corresponding property prefix using @ConfigurationProperties:

 package com.example.app; // Assuming this is your main application package import liquibase.integration.spring.SpringLiquibase;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;

import javax.sql.DataSource;

@SpringBootApplication
// Enable configuration property binding to LiquibaseProperties, allowing us to create multiple instances @EnableConfigurationProperties(LiquibaseProperties.class)
public class DemoApplication { // Can be your main startup class or any @Configuration class public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    /**
     * Create and configure a Liquibase instance for the main application.
     * Bind to properties prefixed with 'spring.liquibase'.
     * 
     * @param dataSource Main data source * @param liquibaseDataSource Liquibase-specific data source (if defined)
     * @param properties LiquibaseProperties bound to 'spring.liquibase'
     * @return configured SpringLiquibase instance*/
    @Bean // "main" liquibase
    // If necessary, you can specify the execution order: @DependsOn("liquibaseLib")
    @ConfigurationProperties("spring.liquibase") // Bind to spring.liquibase.* properties public SpringLiquibase liquibaseMain(
            ObjectProvider<datasource> dataSource,
            @LiquibaseDataSource ObjectProvider<datasource> liquibaseDataSource,
            LiquibaseProperties properties) {
        // Use Spring Boot's internal LiquibaseConfiguration helper class to create a SpringLiquibase instance // This allows you to reuse the logic of Spring Boot's automatic configuration. LiquibaseConfiguration helper = new LiquibaseConfiguration(properties);
        return helper.liquibase(dataSource, liquibaseDataSource);
    }

    /**
     * Create and configure Liquibase instances for external libraries.
     * Bind to properties prefixed with 'lib.liquibase'.
     * 
     * @param dataSource Main data source * @param liquibaseDataSource Liquibase-specific data source (if defined)
     * @param properties LiquibaseProperties bound to 'lib.liquibase'
     * @return configured SpringLiquibase instance*/
    @Bean // lib liquibase
    @ConfigurationProperties("lib.liquibase") // Bind to lib.liquibase.* properties public SpringLiquibase liquibaseLib(
            ObjectProvider<datasource> dataSource,
            @LiquibaseDataSource ObjectProvider<datasource> liquibaseDataSource,
            LiquibaseProperties properties) {
        // Same as above, use the helper class LiquibaseConfiguration helper = new LiquibaseConfiguration(properties);
        return helper.liquibase(dataSource, liquibaseDataSource);
    }
}</datasource></datasource></datasource></datasource>

4.3 Precautions

  • @EnableConfigurationProperties(LiquibaseProperties.class) : This annotation is key, it enables Spring to recognize and bind multiple instances of LiquibaseProperties.
  • @ConfigurationProperties("prefix") : Every SpringLiquibase Bean creation method requires this annotation to specify which property prefix it should load configuration from.
  • LiquibaseAutoConfiguration.LiquibaseConfiguration : Spring Boot provides a LiquibaseConfiguration auxiliary class internally, which encapsulates the logic of creating SpringLiquibase instances from LiquibaseProperties. Using it directly maintains consistency with Spring Boot auto-configuration behavior.
  • ObjectProvider : Spring Boot uses ObjectProvider during auto-configuration to obtain DataSource lazily and flexibly. This pattern is followed here as well. @LiquibaseDataSource can be used to specify a specific data source if your application has multiple data sources.
  • Default SpringLiquibase Bean : If you use @SpringBootApplication, Spring Boot will create a SpringLiquibase Bean with the spring.liquibase prefix by default. By manually defining the liquibaseMain Bean and using @ConfigurationProperties("spring.liquibase"), our custom bean overrides or replaces the default bean, giving us full control.

5. Summary and best practices

  • Choose the right option :
    • Simple plan (Plan 1) : Suitable for scenarios where the configuration is relatively fixed and a small number of Liquibase instances, and you want to control all details directly in the code.
    • Advanced solution (Option 2) : Suitable for scenarios that require a high degree of external configuration, the number of Liquibase instances may change, or you want to be more closely integrated with the Spring Boot automatic configuration mechanism. It provides more flexibility but is slightly more complex to configure.
  • Changelog path : Always specify changelog files using the classpath: prefix to ensure they can be loaded correctly from the JAR package or file system.
  • Execution order : If there are dependencies between database migrations of different modules, be sure to use the @DependsOn annotation to explicitly specify the initialization order of SpringLiquibase Beans to avoid potential database schema inconsistencies.
  • Data source management : Ensure all Liquibase instances point to the correct data source. If your application has multiple data sources, each Spring Liquibase instance needs to be assigned the correct data source based on business requirements.
  • spring.liquibase.change-log in library : If the external library defines spring.liquibase.change-log in its own application.properties, this is usually for standalone testing or demonstrations of the library. When the main application is integrated, the main application's configuration will override or manage these properties, so this property in the library will usually not directly affect the runtime behavior of the main application unless you explicitly load and use it.

Through the above method, you can flexibly manage Liquibase database migrations from multiple sources (main projects and external libraries) in Spring Boot applications to ensure the correctness and consistency of the database schema.

The above is the detailed content of Spring Boot integrates external library Liquibase multiple Changelog management tutorial. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

ArtGPT

ArtGPT

AI image generator for creative art from text prompts.

Stock Market GPT

Stock Market GPT

AI powered investment research for smarter decisions

Popular tool

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to configure Spark distributed computing environment in Java_Java big data processing How to configure Spark distributed computing environment in Java_Java big data processing Mar 09, 2026 pm 08:45 PM

Spark cannot run in local mode, ClassNotFoundException: org.apache.spark.sql.SparkSession. This is the most common first step of getting stuck: even the dependencies are not correct. Only spark-core_2.12 is written in Maven, but spark-sql_2.12 is not added. SparkSession crashes as soon as it is built. The Scala version must strictly match the official Spark compiled version - Spark3.4.x uses Scala2.12 by default. If you use spark-sqljar of 2.13, the class loader cannot directly find the main class. Practical advice: Go to mvnre

How to safely map user-entered weekday string to integer value and implement date offset operation in Java How to safely map user-entered weekday string to integer value and implement date offset operation in Java Mar 09, 2026 pm 09:43 PM

This article introduces a concise and maintainable way to map the weekday string (such as "Monday") to the corresponding serial number (1-7), and use the modulo operation to realize the forward and backward offset of any number of days (such as Monday plus 4 days to get Friday), avoiding lengthy if chains and hard-coded logic.

How to generate a list of duplicate elements using Java's Collections.nCopies_Initialization tips How to generate a list of duplicate elements using Java's Collections.nCopies_Initialization tips Mar 06, 2026 am 06:24 AM

Collections.nCopies returns an immutable view. Calling add/remove will throw UnsupportedOperationException; it needs to be wrapped with newArrayList() to modify it, and it is disabled for mutable objects.

What is exception masking (Suppressed Exceptions) in Java_Multiple resource shutdown exception handling What is exception masking (Suppressed Exceptions) in Java_Multiple resource shutdown exception handling Mar 10, 2026 pm 06:57 PM

What is SuppressedException: It is not "swallowed", but actively archived by the JVM. SuppressedException is not an exception loss, but the JVM quietly attaches the secondary exception to the main exception under the premise that "only one exception must be thrown" for you to verify afterwards. It is automatically triggered by the JVM in only two scenarios: one is that the resource closure in try-with-resources fails, and the other is that you manually call addSuppressed() in finally. The key difference is: the former is fully automatic and safe; the latter requires you to keep it to yourself, and it can be written as shadowing if you are not careful. try-

How to use Homebrew to install Java on Mac_A must-have Java tool chain for developers How to use Homebrew to install Java on Mac_A must-have Java tool chain for developers Mar 09, 2026 pm 09:48 PM

Homebrew installs the latest stable version of openjdk (such as JDK22) by default, not the LTS version; you need to explicitly execute brewinstallopenjdk@17 or brewinstallopenjdk@21 to install the LTS version, and manually configure PATH and JAVA_HOME to be correctly recognized by the system and IDE.

How to correctly implement runtime file writing in Java applications (avoiding JAR internal write failures) How to correctly implement runtime file writing in Java applications (avoiding JAR internal write failures) Mar 09, 2026 pm 07:57 PM

After a Java application is packaged as a JAR, data cannot be written directly to the resources in the JAR package (such as test.txt) because the JAR is essentially a read-only ZIP archive; the correct approach is to write variable data to an external path (such as a user directory, a temporary directory, or a configuration-specified path).

What is the underlying principle of array expansion in Java_Java memory dynamic adjustment analysis What is the underlying principle of array expansion in Java_Java memory dynamic adjustment analysis Mar 09, 2026 pm 09:45 PM

ArrayList.add() triggers expansion because grow() is called when size is equal to elementData.length. The first add allocates 10 capacity, and subsequent expansion is 1.5 times and not less than the minimum requirement, relying on delayed initialization and System.arraycopy optimization.

How to safely read a line of integer input in Java and avoid Scanner blocking How to safely read a line of integer input in Java and avoid Scanner blocking Mar 06, 2026 am 06:21 AM

This article introduces typical blocking problems when using Scanner to read multiple integers in a single line. It points out that hasNextInt() will wait indefinitely when there is no subsequent input, and recommends a safe alternative with nextLine() string splitting as the core.

Related articles