私の java-spring-maven Web アプリケーションでは、複数のスプリング コンテキスト (プロジェクトごとに 1 つのコンテキスト) を使用しています。簡単にするために、2 つのスプリング コンテキスト a.xml と b.xml があり、それぞれがプロジェクト A とプロジェクト B に属し、A が B に依存しているとします。
a.xml は、次のように b.xml をインポートしています。
<import resource="classpath*:/b.xml" />
したがって、a.xml をロードすると、b.xml もロードされます。
現在、私のシステムには 2 つのスプリング プロファイルがあります。コンテキストで使用される testとproductionです (プロファイルごとに異なるプロパティ プレース ホルダーをロードします)。
だから私は得た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-props-for-a)。b.xml は a.xml によってインポートされますが、b.xml からロードされたプロパティ ファイルのプロパティ値が挿入されないという奇妙な経験が発生しました。
たとえば、プロパティ ファイルに次のプロパティがあるとします。
connection-ip=1.2.3.4
そして私のクラスで私は得ました:
@Value("${connection-ip}")
private String connectionIP;
connectionIP の値は、「1.2.3.4」ではなく「${connection-ip}」になります。
ファイルの場所が で始まり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 の下にファイルがはっきりと表示されます。