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

为什么maven将资源保存在Java源的单独“源文件夹”中?

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

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

  1. 你怎么看?
  2. maven是否有充分理由将资源与资源分开?
  3. 有没有使用src/main/resourcessrc/test/resources并使用maven在src/main/javasrc/test/java保存资源的计数器指示?

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

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

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

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

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

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

  org.apache.maven.plugins maven-war-plugin 2.1.1    src/main/java WEB-INF/classes  **/*.properties **/*.xml **/*.htm **/*.html **/*.css **/*.js    src/main/resources  **/log4j.xml      

你怎么看? 我认为Maven背后的人应该进行一些“关注点分离”。 使用Maven的首要原因是依赖管理,但为什么搅拌机应该告诉我如何剥果? 对我来说根本没有意义。

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

我试着自己给出答案。

你怎么看?

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

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中的非标准资源目录位置(请参阅资源和超级pom )。 可以改变maven项目的目录结构,在pom中指定:

   target target/classes ${artifactId}-${version} target/test-classes src/main/java src/main/scripts src/test/java   src/main/resources     src/test/resources    

我没有发现它的特殊问题。

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

我区分这两者的方式是java文件夹默认允许在生成的jar中不构建任何内容,除了我列出的文件类型(例如*.class*.html*.properties如果你使用的是Wicket) ,除了我列出的少数例外, resources所有内容都将被复制到构建中。

当然这只是我的私人会议,我自己坚持。

1)你怎么看?

我认为,这是一个很好的惯例。

2)maven是否有充分理由将资源与资源分开?

是。 你遵循惯例。 拥有项目代码访问权限的每个人都知道在哪里查找代码以及其他所有内容。 当然,测试用例在哪里。 当该插件执行时,将会发生什么文件。

3)是否有任何计数器指示不使用src / main / resources和src / test / resources并使用maven保留src / main / java和src / test / java中的资源?

没有反指示。 这是常规问题,您安排自己的代码的方式没有任何问题。 实际上,如果您创建了一个Wicket项目,您将看到您的HTML和Java代码在Java包中保持并行。 但是,只有Wicket,你知道HTML将在Java文件的一边。 但其他一切都在resources文件夹中。

也许我是这里唯一一个不是来自Java背景的人。 我认为混合资源和代码非常混乱。 关注点分离使您的项目变得更清晰,更容易理解/维护。

我尝试将自己的目录约定应用于我的所有软件开发项目:

  • bin:用户使用的最终二进制文件
  • build:中间二进制文件,它们可能在构建后被删除
  • lib:外部库
  • src:ONLY源代码(在本例中为Java源文件)
  • 资源:所有资源(配置文件,xmls,图像,html等)
  • docs:文档

当我需要更改此目录结构时,我很少找到开发上下文。

使用Maven,如果要进行快速设置,请使用默认值。 如果要使用目录约定,只需更改pom.xml中的设置,如前所述。 但请注意,某些Maven插件会考虑将默认的Maven目录用于资源/源/输出二进制文件,如果更改这些目录,则需要调整一些插件设置。

我认为代码/资源分离通常很有用:

  1. 包必须遵循Java规范规则,例如不允许使用保留字,如’int’。 在源代码文件夹中包含非法包会令人困惑。

  2. 资源具有实例性,类具有类性质。 例如,您可能在同一个包中有类ContinentCountry ,但资源更好地组织为树:

    • 非洲/
      • morocco.txt
      • kenya.txt
    • 欧洲/
      • poland.txt
  3. 在我看来,资源结构比代码结构更稳定。 代码重构经常发生,类从包到包移动以获得更好的可读性。 在重构上移动资源的义务阻碍了开发人员重构。

  4. 如果甚至仅对1%的资源文件需要分离的资源文件夹,则将剩余的99%移动到该文件夹​​并将资源仅保留在单个位置是合理的。

但是,有些情况下将资源和Java代码保持在一起很有用。 例如,unit testing比较输入和输出 – 很高兴将文件与输入和输出放在与unit testing代码相同的文件夹中。