如何从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的配置体系,可以通过上下文持有类读取属性:
- 先创建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); } }
- 修改自定义任务类,去掉
@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对象中的参数配置:
- 利用上面的
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
相关产品推荐
相关产品推荐

