28

我的 WEB-INF 目录下有一些 XML 文件:

  • 歌词BaseApp-servlet.xml
  • 休眠.xml
  • 数据源.xml
  • 豆类.xml

servlet xml 导入其他 xml 文件:

<import resource="dataSource.xml"/>
<import resource="hibernate.xml"/>
<import resource="beans.xml"/>

我希望我的 junit4JukeboxTest类包含整个弹簧配置。使用默认文件名我创建了一个JukeboxTest-content.xml文件。最后,我不知道该放什么...

我试过了:

<import resource="/WEB-INF/dataSource.xml"/>
<import resource="/WEB-INF/hibernate.xml"/>
<import resource="/WEB-INF/beans.xml"/>

或者

<import resource="classpath:./WEB-INF/dataSource.xml"/>
<import resource="classpath:./WEB-INF/hibernate.xml"/>
<import resource="classpath:./WEB-INF/beans.xml"/>

和其他一些想法,但都失败了。有人可以指出我如何访问这些文件以及 spring 以什么方式解释这些文件路径?

4

2 回答 2

86

选项 1(应该是首选,因为它是最佳实践):
重构您的配置文件WEB-INF并将公共部分(您也希望从集成测试访问)移动到src/main/resources/. 然后写入测试特定的配置文件src/test/resources/(如果你只需要导入几个不同的配置文件src/main来组装你的测试上下文,那么跳过这个,@ContextConfiguration最好使用)。

选项 2(hack):
使用如下引用:

@ContextConfiguration("file:src/main/webapp/WEB-INF/dataSource.xml")

选项 3(hack):
如果您有一个 Maven 项目,您可以配置maven-surefire-plugin(在测试阶段使用)src/main/webapp在测试执行期间声明为附加的类路径元素。

后两个选项被认为是 hack,因为下面的文件src/main/webapp根本不应该在类路径上。

现在详细解释:

您不能按原样引用这些文件的原因classpath:/WEB-INF/*.xml是它们确实不在类路径中。了解您的 web 应用程序是如何打包的,以及类路径中的最终结果是什么,这一点很重要。假设一个默认的 Maven 项目结构:

  1. Java 类从src/main/javago 到/WEB-INF/classes编译后。
  2. src/main/resourcesgo to的资源/WEB-INF/classes也是。
  3. 项目依赖项转到/WEB-INF/lib.
  4. 你所拥有的一切都src/main/webapp进入/(包的根目录)。这意味着从src/main/webapp/WEB-INFgo 到的所有文件/WEB-INF,当然。

要知道的最重要的事情是,类路径将只包含/WEB-INF/classes一个条目,每个 jar 在/WEB-INF/lib. 因此,这两个位置之外的资源对于类加载器来说是完全不可见的。直接在 下 的 xml 配置文件也是如此/WEB-INF,这就是为什么引用classpath:/WEB-INF/dataSource.xml永远不会起作用的原因。

您可能会问自己,如果这些 xml 配置文件无法从类路径访问,那么这些 xml 配置文件是如何被 Spring 加载的呢?答案很简单:当你启动你的 webapp(而不是只执行单元/集成测试)时,它运行在一个 Servlet 容器中,它提供了对ServletContext(来自 Servlet API 的一个实际类)的访问,所以它ServletContext.getResourceAsStream()用来加载这些文件。理解的关键是该方法的javadoc中的以下引用:

此方法与使用类加载器的 java.lang.Class.getResourceAsStream 不同。此方法允许 servlet 容器从任何位置为 servlet 提供资源,而无需使用类加载器。

对不起,这变得太长了,但这就是整个故事......

于 2013-02-18T22:25:18.767 回答
12

尝试这个

@ContextConfiguration(locations = {"classpath:**/dataSource.xml",
                               "classpath:**/hibernate.xml", 
                               "classpath:**/WEB-INF/beans.xml"})
于 2013-02-19T07:46:40.603 回答