2015-04-01 106 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