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

如何从Spring Boot Java类中读取Liquibase参数

Liquibase自定义任务读取Spring Boot动态参数为null的解决方法

问题场景

我在Liquibase脚本中通过customTaskChange调用Spring Boot类,由于参数是动态的,直接从Liquibase传递会触发校验和无效报错,因此未采用该方式。相关代码和配置如下:

Liquibase脚本

<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.6.xsd">

    <changeSet id="update" author="abc" runAlways="true">
        <customChange class="com.med.yc.facility.util.MainConfigurationUpdate"/>
    </changeSet>
</databaseChangeLog>

application.properties配置

spring.liquibase.parameters.a=dynamic_abc
spring.liquibase.parameters.d=dynamic_def

Java自定义任务类

@Configuration
@EnableConfigurationProperties(LiquibaseProperties.class)
public class MainConfigurationUpdate implements CustomTaskChange {

    private ResourceAccessor resourceAccessor;

    @Value("${a}")
    private String a;
    @Value("${d}")
    private String d;

    @Override
    @Transactional
    public void execute(Database database) throws CustomChangeException {
        System.out.println(a);
        System.out.println(d);
    }

    @Override
    public String getConfirmationMessage() {
        return null;
    }

    @Override
    public void setUp() throws SetupException {
        //do nothing
    }

    @Override
    public void setFileOpener(ResourceAccessor resourceAccessor) {
        this.resourceAccessor = resourceAccessor;
    }

    @Override
    public ValidationErrors validate(Database database) {
        return null;
    }
}

目前Java类中读取a和d属性始终返回null,需要解决该问题。


核心原因

Liquibase的CustomTaskChange实例是由Liquibase自身实例化的,不属于Spring容器管理范畴,因此Spring的@Value注解无法生效,自然读取不到配置属性。


解决方法

方法一:直接通过Liquibase的Database对象获取参数

Liquibase会自动将spring.liquibase.parameters下的配置注入到Database实例的属性中,直接读取即可:

@Override
@Transactional
public void execute(Database database) throws CustomChangeException {
    String a = database.getProperty("a");
    String d = database.getProperty("d");
    System.out.println(a);
    System.out.println(d);
}

这种方式无需依赖Spring注解,完全利用Liquibase自身的参数机制,还能避免校验和失效的问题,是最推荐的方案。

方法二:通过Spring上下文手动获取配置

如果必须依赖Spring的配置体系,可以通过上下文持有类读取属性:

  1. 先创建Spring上下文持有类:
@Component
public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static String getProperty(String key) {
        return context.getEnvironment().getProperty(key);
    }
}
  1. 修改自定义任务类,去掉@Configuration和@Value,改用上下文读取:
public class MainConfigurationUpdate implements CustomTaskChange {

    private ResourceAccessor resourceAccessor;

    @Override
    @Transactional
    public void execute(Database database) throws CustomChangeException {
        String a = SpringContextHolder.getProperty("spring.liquibase.parameters.a");
        String d = SpringContextHolder.getProperty("spring.liquibase.parameters.d");
        System.out.println(a);
        System.out.println(d);
    }

    // 其他方法保持不变
}

注意:需确保SpringContextHolder已被Spring初始化,且Liquibase启动时Spring上下文已就绪。

方法三:通过LiquibaseProperties读取参数

直接读取Spring Boot的LiquibaseProperties对象中的参数配置:

  1. 利用上面的SpringContextHolder获取LiquibaseProperties:
public class MainConfigurationUpdate implements CustomTaskChange {

    private ResourceAccessor resourceAccessor;
    private LiquibaseProperties liquibaseProperties;

    @Override
    public void setUp() throws SetupException {
        this.liquibaseProperties = SpringContextHolder.getBean(LiquibaseProperties.class);
    }

    @Override
    @Transactional
    public void execute(Database database) throws CustomChangeException {
        String a = liquibaseProperties.getParameters().get("a");
        String d = liquibaseProperties.getParameters().get("d");
        System.out.println(a);
        System.out.println(d);
    }

    // 其他方法保持不变
}

这种方式完全贴合Spring Boot的配置体系,适合需要批量读取Liquibase参数的场景。


内容的提问来源于stack exchange,提问作者Divyani Garg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:02:56