当有人使用ResourceLoader.getResource(...)方法时,有人能解释Spring如何决定在哪里寻找资源?
我遇到使用Spring Boot构建的多模块maven应用程序的问题,在我的集成测试中,我的代码能够使用resourceLoader.getResource("templates/")
甚至resourceLoader.getResource("classpath:templates/")
查找资源。到目前为止一切都很好......
但是,当模块最终打包到可执行JAR中并使用嵌入式Tomcat运行时,无法再解析资源。我也试过resourceLoader.getResource("classpath*:templates/")
但没有成功。
我发现的问题是,当我添加一个日志语句来输出搜索中使用的URL时,我会获得项目中其他模块之一的路径(而不是实际包含相关资源的模块)。例如:jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module1-0.0.1-SNAPSHOT.jar!/templates/
而我相信资源位于jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module2-0.0.1-SNAPSHOT.jar!/templates/
资源加载器是从Autowired构造函数param。
获得的提前感谢任何提示。
如果它不清楚或非常重要,我对相关模块的集成测试并不了解其他模块。我有module1,module2和spring-boot模块,它依赖于module1&模块2。基本上,当我运行模块2的集成测试时,类路径并不知道module1 - 所以我怀疑这与它在测试中的工作原理有关。
答案 0 :(得分:2)
在内部使用classpath:
或classpath*:
前缀时,这通常是在Spring中通过ClassLoader.getResources(...)调用发生的。
通配符类路径依赖于底层类加载器的getResources()方法。由于现在大多数应用程序服务器都提供了自己的类加载器实现,因此行为可能会有所不同,尤其是在处理jar文件时。检查classpath *是否有效的简单测试是使用类加载器从类路径中的jar中加载文件:
getClass().getClassLoader().getResources("<someFileInsideTheJar>")
。尝试使用具有相同名称但放在两个不同位置的文件进行此测试。如果返回了不适当的结果,请检查应用程序服务器文档以获取可能影响类加载器行为的设置。
不要使用classpath:
表单,因为您有templates/
的多个类加载器位置。