2015-04-01 107 views
0

我在評論一個小型的github示例項目(shagie/TestingWithHsqldb),並且偶然發現了一個新的約定,希望有人能幫助我理解我在看什麼。類加載器如何找到資源?


該項目的主要src目錄這樣組織下...

src/main/resources/connection_config.properties 
src/main/java/com/shagie/dbtest/db/DBConnection.java 
src/main/java/com/shagie/dbtest/db/DataAccess.java 

src/test/resources/connection_config.properties 
src/test/java/com/shagie/dbtest/db/DataAccessTest.java 

DBConnection.java的代碼都來自DataAccess.java「主」目錄,以及在該DataAccessTest.java下稱爲'測試'目錄。

在文件DBConnection.java有以下語句導入connection_config.properties文件:

Properties prop = new Properties(); 
InputStream in = GetClass().getResourceAsStream("/connection_config.properties"); 
prop.load(in); 
in.close(); 

我的問題......

  • 如何屬性文件中被找到「資源」目錄如果呼叫的結構爲getResourceAsStream("/connection_config.properties")?不是那個路徑意味着它應該查看屬性文件的根目錄(主目錄或測試目錄)?

  • 由於DBConnection.java不會改變它的根「主」目錄下,它是如何執行DataAccessTest.java

  • 當屬性文件來自於「測試」目錄我假設依賴注入這種模式與和單元測試。這種特定模式有沒有名稱?哪裏可以更好地瞭解它?

編輯:調整問題,把重點放在ClassLoadergetResource的功能,而不是依賴注入

回答

1

這有什麼好做的依賴注入但是如何ClassLoader的決心資源路徑。

1)這可能有點混淆來自Linux背景確實getResourceAsStream(resource)有不同的規則。具體根據doc

如果名字用「/」(「\ u002f」)開始,然後的 資源的絕對名稱是繼「/」的名稱的一部分。

所以斜線這裏只告訴類裝載器如何獲得絕對名稱(無論你通過名稱應與包名前置或沒有),而不是它應該尋找「在根」 (在測試/主文件夾中)。什麼是根和解決方案如何工作取決於您正在使用的類加載器。默認情況下(在這種情況下)在resources文件夾中搜索資源。您可以編寫自己的ClassLoader並更改該行爲。

2)同樣,當呼叫getResources()getResourceAsStream()時,該類將其委派給加載該類的ClassLoader。如果您正在運行單元測試(Junit或類似的),那麼ClassLoader將知道它應該查找test文件夾中的資源,而不是main

+0

源代碼中沒有任何跡象表明它正在使用除默認類加載器之外的任何東西(如果情況並非如此,我怎麼知道我是否使用了默認類加載器以外的東西?)。如果'/ connection_config.properties'是絕對名稱,那麼我不明白類加載器如何知道在'resources'目錄中查找。 我查看了文檔網站上的[位置無關資源訪問](http://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html)指南,以及它對我來說沒有更清楚的理由,爲什麼'resources'目錄將被用來查找文件。 – 2015-04-01 13:39:17

+0

@HariSeldon啊這裏有一點誤解,它不一定要在'resources'目錄下,這就是現在Java中使用的項目佈局約定。把它放在其他地方,它應該仍然有效。 – 2015-04-01 14:17:56

+0

好的......這使得它更加清晰......我將爲自己制定一些示例代碼。感謝您花時間:) – 2015-04-01 14:32:28