如何让Flyway仅从指定JAR依赖中执行SQL迁移脚本?
解决方案
方法1:通过唯一资源路径隔离(最简单)
修改com.example:sql-migrations JAR中迁移脚本的存放路径,从src/main/resources/db/migration改为更具唯一性的专属路径,比如:
src/main/resources/db/migration/com/example/sql-migrations
然后在依赖项目的Flyway配置中指定这个唯一路径:
flyway.locations("classpath:db/migration/com/example/sql-migrations")
这样Flyway只会扫描这个专属路径下的脚本,从根源上避免和其他JAR的同路径脚本冲突,彻底解决安全顾虑。
方法2:自定义ResourceProvider过滤特定JAR
如果不想修改脚本路径,可以通过自定义Flyway的ResourceProvider来限制仅从目标JAR加载资源。
实现步骤:
- 自定义
FilteredClassPathResourceProvider,继承Flyway的ClassPathResourceProvider,重写资源加载逻辑,过滤出目标JAR的资源:
import org.flywaydb.core.api.resource.LoadableResource; import org.flywaydb.core.internal.resource.classpath.ClassPathResourceProvider; import java.net.URL; import java.util.List; import java.util.stream.Collectors; public class FilteredClassPathResourceProvider extends ClassPathResourceProvider { // 匹配目标JAR的文件名特征,比如包含groupId和artifactId的前缀 private static final String TARGET_JAR_MARKER = "com.example.sql-migrations-"; public FilteredClassPathResourceProvider(ClassLoader classLoader, String location) { super(classLoader, location); } @Override protected List<LoadableResource> findResources(String location) { List<LoadableResource> allResources = super.findResources(location); // 过滤仅保留来自目标JAR的资源 return allResources.stream() .filter(resource -> { URL resourceUrl = resource.getUrl(); String urlStr = resourceUrl.toString(); return urlStr.contains(TARGET_JAR_MARKER); }) .collect(Collectors.toList()); } }
- 在Flyway配置中使用自定义的ResourceProvider:
Flyway flyway = Flyway.configure() .dataSource(yourDataSource) .resourceProvider(new FilteredClassPathResourceProvider( Thread.currentThread().getContextClassLoader(), "classpath:db/migration" )) .load(); flyway.migrate();
为什么你尝试的写法无效?
Java标准的类路径资源定位语法并不支持classpath:com.example:sql-migrations!db/migration这种通过Maven坐标指定JAR的方式。Flyway默认的资源加载逻辑是基于ClassLoader扫描所有类路径下的匹配资源,没有内置按JAR坐标过滤的功能,所以这种写法无法被解析。
内容的提问来源于stack exchange,提问作者mohamnag
相关产品推荐
相关产品推荐

