Spring bean配置文件在Maven WAR模块中应该放在哪里?

9

我看了很多示例项目,似乎无法找出一种通用的最佳实践。有时候我看到Spring bean配置文件放在src/main/webapp/WEB-INF目录下。我也看到这与web.xml中的Servlet定义一起使用,就像这样:

<servlet>
    <servlet-name>my-stuff</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/my-stuff-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

但我也看到Bean配置文件包含在web.xml的顶层 - 也就是Servlet之外。这是什么意思?这是为了跨Servlet Bean吗?有时它在src/main/webapp/WEB-INF目录中,有时它在src/main/resources中。此外,我还看到其他Bean配置文件定义在WAR模块中,几乎所有内容都在src/main/resources中。
我已经阅读并反复阅读了Spring文档,但我发现唯一的约定是默认情况下Servlet上下文配置文件应该在src/main/webapp/WEB-INF目录中命名为{servlet-name}-servlet.xml
那么最佳实践是什么以及为什么?
2个回答

12

在Spring中,应用程序上下文可以形成层次结构,其中子上下文可以访问父上下文中定义的Bean。

典型的Spring MVC Web应用程序包含两个层次结构:

  • ContextLoaderListener加载的根Web应用程序上下文。此上下文的配置位置默认为applicationContext.xml,可以使用<context-param>命名为contextConfigLocation来配置,在web.xml的顶级进行配置。此上下文通常包含核心应用程序逻辑。

  • DispatcherServlet加载的特定于Servlet的上下文。它的配置位置默认为<servletname>-servlet.xml,可以使用<init-param>命名为contextConfigLocation在Servlet级别进行配置。该上下文通常包含Spring MVC相关内容(控制器等),因为DispatcherServlet是Spring MVC的一部分。

后者的上下文是前者的子级。

如果Web应用程序不使用Spring MVC作为表示框架,则不会有DispatcherServlet及其上下文。一些极其简单的Spring MVC示例没有ContextLoaderListener和根上下文(但是,您需要根上下文来进行跨Servlet功能,例如Spring Security)。

Web应用程序的配置文件默认位于Webapp的根文件夹中。但是,它们可以放置在类路径中(即在src/main/webapp中),在这种情况下,它们通过classpath:前缀访问。如果您要在没有Servlet容器的集成测试中使用其中一些文件,则这可能很有用。此外,classpath:前缀可能在您想从单独的工件加载配置文件时非常有用,例如,在/WEB-INF/lib中的JAR文件中。


非常有帮助 - 谢谢。希望在Spring文档中也能这么好地解释! - Dave
@HDave 这不是Spring特定的,而是普通的Java类加载器行为(唯一与Spring相关的是classpath:前缀)。 - Sean Patrick Floyd

2
我认为将代码、Spring配置文件放在一个单独的JAR包中,并将其包含在WAR中,使得WAR基本上是空的(仅有web.xml等文件),这通常是很好的风格。这样做可以避免您甚至提出这个问题。:-) 您可以使用classpath:前缀引用这些Spring配置文件。
这种布局的一个优点是,您可以轻松编写单元测试,实例化JAR中WAR的完整Spring配置。我不一定建议将其用于实际测试(尽管您可以通过这种方式进行集成测试),但当您意外破坏配置文件的整体结构时,可以快速获得反馈而无需重新部署应用程序。
如果您真的需要将Spring配置文件放入WAR中(也许因为它还引用了在WAR本身中实现的bean),我也会将它们放入正常的资源路径/WEB-INF/classes中,原因如上所述。

我同意这一点,并且已经在那些模块JAR中拥有了所有的模块级Spring配置文件,因为正如您所提到的那样,这是为了集成测试。然而,仍然存在WAR级别的Spring配置文件,我需要它们来创建实例以供servlet容器等使用。最终,我只好把它们放在{{webapp}}目录下。 - Dave
@HDave 我会把这些文件放到/WEB-INF/classes中,这样它们也在类路径中。这样你至少可以适当地进行单元测试。 - Hans-Peter Störr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接