Spring Boot测试环境中ResourceLoader无法加载主资源目录文件
解决方案
问题本质是Maven测试阶段默认将test-classes(对应src/test/resources)的类路径优先级设为高于classes(对应src/main/resources),导致类加载器优先查找测试资源。以下是几种可行的解决方式:
方案1:调整Maven测试类路径顺序(构建层面)
修改pom.xml中的maven-surefire-plugin配置,让主资源目录的类路径优先级更高:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <!-- 优先加载主资源目录,再加载测试资源目录 --> <classpathOrder>classes,test-classes</classpathOrder> </configuration> </plugin> </plugins> </build>
配置后,测试时类加载器会先查找src/main/resources下的资源,仅当主目录无匹配文件时才会去测试目录查找。
方案2:代码层面优先筛选主资源
若不想修改构建配置,可在代码中手动扫描并优先选择主资源目录的文件:
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("classpath*:" + path); // 优先选择来自主资源目录(路径包含/classes/)的资源 for (Resource resource : resources) { String resourcePath = resource.getURL().getPath(); if (resourcePath.contains("/classes/")) { return new String(Files.readAllBytes(resource.getFile().toPath())); } } // 主目录无匹配时, fallback到第一个找到的资源 if (resources.length > 0) { return new String(Files.readAllBytes(resources[0].getFile().toPath())); } throw new RuntimeException("Resource not found: " + path);
该方法通过扫描所有匹配的classpath资源,筛选出主资源目录下的文件优先加载。
方案3:使用Spring注入的ResourceLoader(推荐)
避免自行实例化DefaultResourceLoader,通过Spring依赖注入获取资源加载器,并优先尝试加载主资源:
// 注入Spring管理的ResourceLoader @Autowired private ResourceLoader resourceLoader; public String loadResource(String path) throws IOException { // 先尝试用主类的类加载器加载主资源 Resource mainResource = new ClassPathResource(path, MyClass.class.getClassLoader()); if (mainResource.exists()) { return new String(Files.readAllBytes(mainResource.getFile().toPath())); } // 主资源不存在时, fallback到测试资源 Resource testResource = resourceLoader.getResource(path); return new String(Files.readAllBytes(testResource.getFile().toPath())); }
利用ClassPathResource绑定主类的类加载器,优先加载src/main/resources下的文件。
内容的提问来源于stack exchange,提问作者Smajl
相关产品推荐
相关产品推荐

