为什么项目布局资源与Java源代码分开?

Lui*_*ano 18 java resources layout maven

为什么maven将资源保存在与Java源不同的"源文件夹"中?

根据我的经验,在Java中,资源文件大多被视为Java源文件,当"编译"时,只需要按类复制,最终打包在jar中,并通过类加载器的方法访问getResource/ getResourceAsStream,通过classpath.

我个人认为将资源文件与Java源代码分开是一种无用的复杂性.

  1. 你怎么看?
  2. maven是否有充分理由将资源与资源分开?
  3. 有没有在不使用任何计数器指示src/main/resourcessrc/test/resources守信资源src/main/javasrc/test/java使用Maven?

jta*_*orn 15

尚未提出的一点是,您显然习惯于看到仅包含Java源的项目.但是,如果你投入其他一些源文件类型,我认为组织更有意义,例如:

  • SRC /主
    • 资源
    • java的
    • 常规

每个子目录都有一个特定的文件分类:

  • java - >编译为java文件的东西
  • groovy - >编译为groovy脚本的东西
  • 资源 - >用于任何...的未编译数据...(也可以过滤这些数据以添加编译时信息)

另外(正如我已经在一些评论中指出的那样),我通常不会使资源目录变平.文件可以嵌套到类似于包的结构中,也可以嵌套到其他子目录中(根据我的组织意识).

  • 那么,如果我有一些特定于java代码的资源,并且某些资源特定于groovy代码呢? (3认同)

gui*_*ido 8

为了简单和更容易访问,我们在java源路径中保留了一些资源.这使得我们在GUI级别上作为速度模板进行开发时非常方便,因此它们接近于控制器Java代码.但你必须告诉maven在src/main/java中包含非java东西,通过在你的pom文件中添加这样的东西.

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                <webResources>
                    <resource>
                        <directory>src/main/java</directory>
                        <targetPath>WEB-INF/classes</targetPath>
                      <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                        <include>**/*.htm</include>
                        <include>**/*.html</include>
                        <include>**/*.css</include>
                        <include>**/*.js</include>
                      </includes>
                    </resource>
                    <resource>
                        <directory>src/main/resources</directory>
                      <excludes>
                        <exclude>**/log4j.xml</exclude>
                      </excludes>
                    </resource>
                </webResources>
                </configuration>
            </plugin>
Run Code Online (Sandbox Code Playgroud)


Joe*_*oel 6

What do you think? I think that the guys behind Maven should exercise a little "separation of concerns". The number one reason to use Maven is for dependency management, but why should a blender tell me how to peel my fruit? It makes no sense to me at all.

maven是否有充分理由将资源与资源分开?在一个java项目中,包结构的重复,不是一次,而是三次,给项目增加了不必要的工作,增加了错误的风险并降低了代码的敏捷性.


Lui*_*ano 5

我尝试自己给出答案。

你怎么认为?

这是无用的额外复杂性。因此是错误的:见下文。

Maven 将资源与源分开是否有充分的理由?

我可能想到的唯一原因是,对于某些平台来说,这可能是一个很好的做法。例如,在 Mac OSX 应用程序中,资源与二进制文件分开打包(在不同的子文件夹中)。

我认为“外部”资源和配置文件,即那些没有打包到最终工件(jar 文件)中的资源和配置文件,有充分的理由与源文件分开。因此,当maven打包jar时,他知道这些文件不必包含在内,因为例如,我们希望它们位于jar之外,以便允许用户编辑这些文件作为配置。

但是,对于打包在 jar 中的内容(如翻译字符串和 xml 元数据,如 hibernate 映射和 spring 配置),没有充分的理由将它们放在单独的位置,除非我们希望用户更改它们作为配置过程的一部分,部署后手动进行。

资源可以使用与类相同的包结构来组织,因此,如果您在包 xyz 中有一个类,您可能希望在同一个包中拥有它所依赖的资源,因为它们代表相同的“逻辑单元”:在这种情况下,将它们放在两个单独的文件夹中会导致在包重构和重组期间需要额外注意,因为您希望保持内容同步。ClassLoader 还提供了在 getResourceAsStream() 方法中指定相对路径的可能性。因此,如果您有类 xyzMyClass,则可以执行 getClass().getResourceAsStream("foo-bar.properties"),并且资源将从同一包“xyz”加载。因此,当它们具有紧密的依赖性时,将它们保持在一起非常有用。

对于在可部署工件中也需要保持独立的外部资源,将它们保持独立是一件好事,但在这种情况下,我不明白为什么 Maven 将 src/main/resources 视为“java 源文件夹” (maven-eclipse-plugin) 因为它们实际上不能在类路径中,而是通过文件系统作为普通文件访问,特别是您不希望这些文件在 Maven 构建期间包含在 jar 中。这是应用程序图标、您可能想要放置在 /etc 目录中的配置文件等的情况。

总之,在我看来,maven 处理资源的方式有问题:如果它们是“外部”资源,那么 maven 就没有理由将它们打包到最终的工件(jar)中。如果它们不是“外部”,则没有理由将它们保存在单独的“源文件夹”中。

不使用 src/main/resources 和 src/test/resources 并使用 maven 将资源保留在 src/main/java 和 src/test/java 中是否有任何反指示?

我不知道。

大多数时候我使用默认的 Maven 布局来处理资源,但有几次我没有这样做;采取预防措施在 pom 中声明非标准资源目录位置(请参阅resourcessuper-pom)。可以更改 maven 项目的目录结构,在 pom 中指定:

 <build>
    <directory>target</directory>
    <outputDirectory>target/classes</outputDirectory>
    <finalName>${artifactId}-${version}</finalName>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <sourceDirectory>src/main/java</sourceDirectory>
    <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
      </testResource>
    </testResources>
  </build>
Run Code Online (Sandbox Code Playgroud)

而且我没有发现它有什么特别的问题。

我希望 Maven 人员再次考虑一下这个约定,因为拥有更简单的项目结构可以帮助开发人员更多地专注于开发,而不是在浏览应用程序代码时在项目结构中的多个文件夹周围查找内容。