在我的 java-spring-maven web-application 中,我使用了多个 spring 上下文(每个项目的单个上下文)。为了简单起见,假设我有 2 个 spring 上下文:a.xml 和 b.xml,每个都属于一个项目:项目 A 和项目 B,其中 A 依赖于 B。
a.xml 正在像这样导入 b.xml:
<import resource="classpath*:/b.xml" />
因此,在加载 a.xml 时,也会加载 b.xml。
现在,我的系统中有 2 个弹簧配置文件:我的上下文使用的测试和生产(为每个配置文件加载不同的属性占位符)。
所以在 a.xml 我得到了:
<!-- Production profile -->
<beans profile="production">
<context:property-placeholder
location="classpath:props-for-a.properties"
ignore-unresolvable="true" ignore-resource-not-found="true" />
</beans>
<!-- Test profile -->
<beans profile="test">
<context:property-placeholder
location="classpath*:test-props-for-a.properties"
ignore-unresolvable="true" />
</beans>
和 b.xml 中的相同约定(仅加载不同的属性文件)。我的属性文件位于 src/main/resources(生产文件)和 src/test/resources(测试文件)下。
现在我有这个看起来像这样的单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/a.xml" })
@ActiveProfiles(profiles = "test")
public class SomeTestClass {
@Test
public void testMethod() {
//Some Test
}
}
在这种情况下,a.xml 被加载到“test”配置文件中,并按预期加载所需的文件(test-props-for-a)。b.xml 是由 a.xml 导入的,但现在我遇到了一种奇怪的体验,我从 b.xml 加载的属性文件中的属性值没有被注入。
例如,如果我的属性文件中有这个属性:
connection-ip=1.2.3.4
在我的课上我得到了:
@Value("${connection-ip}")
private String connectionIP;
connectionIP 的值将是“${connection-ip}”而不是“1.2.3.4”。
请注意,文件位置以 开头classpath*
,没有 * 我得到 FileNotFoundException:
Caused by: org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [test-props-for-b.properties] cannot be opened because it does not exist
需要明确的是,文件 test-props-for-b.properties 位于项目 B 的 src/test/resources 下。为什么我会得到这个?
如果我运行一个直接加载 b.xml(不是通过 a.xml 导入)的测试,它工作得很好,文件 test-props-for-b.properties 中的测试属性会按预期加载。
难道我做错了什么?这可能是一个错误吗?如果是这样,你能建议一个解决方法吗?
更新
我从属性文件 (test-props-for-b.properties) 的路径中删除了星号 (*) 并调试了 spring 代码。在 ClassPathResource 类中,此方法引发异常:
public InputStream getInputStream() throws IOException {
InputStream is;
if (this.clazz != null) {
is = this.clazz.getResourceAsStream(this.path);
}
else {
is = this.classLoader.getResourceAsStream(this.path);
}
if (is == null) {
throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
}
return is;
}
以下是变量值:
this.clazz 为空。this.path 包含文件名test-props-for-b.properties
此命令返回 null:
this.classLoader.getResourceAsStream(this.path);
这是为什么?我可以清楚地看到项目 B 的 src/test/resources 下的文件。