Spring Boot+Tomcat下为Liquibase 3.5.3配置独立JNDI数据源问题
解决方案:为Liquibase和应用配置不同的JNDI数据源(Spring Boot + Liquibase 3.5.3)
我刚好遇到过类似的场景,Liquibase 3.5.3确实没有直接支持通过配置属性指定JNDI数据源的选项,不过我们可以通过自定义Spring配置来解决这个问题,下面是具体的实现方案:
首先,先调整你的application.properties,把应用的主数据源指定为jdbc/DS,确保业务逻辑使用这个连接池:
# 应用主数据源(业务逻辑使用) spring.datasource.jndi-name=java:comp/env/jdbc/DS # Liquibase基础配置(变更日志路径等,根据你的实际情况调整) spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.xml spring.liquibase.enabled=true
接下来,通过自定义配置类手动为Liquibase指定JNDI数据源jdbc/DSAdmin:
自定义Liquibase配置类
创建一个LiquibaseConfig.java配置类,手动从JNDI拉取DSAdmin数据源,并绑定到Liquibase实例:
import liquibase.integration.spring.SpringLiquibase; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jndi.JndiTemplate; import javax.sql.DataSource; @Configuration public class LiquibaseConfig { // 从JNDI获取Liquibase专用的DSAdmin数据源 @Bean(name = "liquibaseDataSource") public DataSource liquibaseDataSource() throws Exception { JndiTemplate jndiTemplate = new JndiTemplate(); // 注意这里的JNDI路径要和你context.xml中配置的ResourceLink name完全一致 return (DataSource) jndiTemplate.lookup("java:comp/env/jdbc/DSAdmin"); } // 配置Liquibase实例,绑定专用数据源 @Bean public SpringLiquibase liquibase(DataSource liquibaseDataSource) { SpringLiquibase liquibase = new SpringLiquibase(); liquibase.setDataSource(liquibaseDataSource); // 变更日志路径要和application.properties中的配置保持一致 liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.xml"); // 可选:添加其他Liquibase配置,比如环境上下文、默认Schema等 // liquibase.setContexts("dev,test"); // liquibase.setDefaultSchema("your_schema_name"); return liquibase; } }
关键注意事项
- JNDI路径正确性:确保
jndiTemplate.lookup中的路径和你Tomcatcontext.xml里的ResourceLink的name属性完全匹配,格式为java:comp/env/[ResourceLink名称]。 - 版本兼容性:Liquibase 3.5.3对应Spring Boot 1.5.x系列,如果你的Spring Boot版本是2.x,建议升级Liquibase版本,但如果必须保留3.5.3,这个方案依然有效。
- Tomcat配置验证:确认Tomcat的
server.xml和context.xml中的Resource、ResourceLink配置没有拼写错误,且应用部署在该Tomcat实例上,JNDI资源能被正确加载。
验证配置
启动应用后,查看Liquibase的启动日志,会看到它连接的是dbname(DSAdmin对应的数据库),而应用业务代码会使用database(DS对应的数据库),这样就实现了两者使用不同数据源的需求。
内容的提问来源于stack exchange,提问作者jeeva
相关产品推荐
相关产品推荐

