1. 为什么写这篇文章

  在之前的javaSE开发中,没有很关注Eclipse工程目录下的环境,总是看见一个src就点进去新建一个包再写一个class。以后的日子中也没有机会注意到一个工程到底是怎么组织的这种问题,更不要说自己试试怎么控制了。

  但是最近在学习Maven的时候知道了它对工程的目录结构有要求,也就是所谓的“惯例优于配置”。有一个被绝大多数人认可的java工程的目录结构被确定下来。这样统一了市面上各种复杂配置的工程。于是我便重新开始查资料,看看别人到底如何安排一个优秀的工程框架的。

  同时,我也分析了Eclipse会给一个项目生成什么配置文件,其中的内容和意义又是什么.这样能心里面大致有个数,本地的什么文件是干什么的,怎么来的。

2. 一个简单的J2SE工程目录结构

  首先,Mac中,一个默认的Eclipse工程的目录结构:

  • MyProject:工程的名字
  • src:一个源文件文件夹
  • com.jd.MyProject:一个包。一般是倒写的域名保证其独一无二性。
  • Main.java:一个java文件。

看上去就这么多?其实不是的,在我的mac环境下,一般时候Eclipse左边的目录是Package Explorer,也是是如上图显示的内容。但是其实可以用另外一个显示其真正的目录,也就是包含一些隐藏文件。叫Navigator(事实上Package Explorer默认隐藏Linux系统下的以.开头的隐藏文件,所以看不见,而Navigator默认打开)。显示效果如下:

3. 为什么Eclipse能认出来这些?

  那么除了这些之外,其实还有值得探究的部分:

  • 为什么Eclipse能识别出这个一个Maven工程?
  • Eclipse怎么识别Source Folder?

  这些问题可以提出很多,其实本质上都是:Eclipse是一个集成开发环境,而Maven是一种项目管理及自动构建工具(维基百科),Eclipse没有责任去“识别”Maven。这句话乍一听感觉和直觉不相符合:明明新建工程的时候选择新建一个Maven工程,Eclipse就知道这是一个Maven工程啊?明明导入一个Maven工程,Eclipse就能正确识别打开啊?

  其实是Eclipse帮我们做了很多。所以问题的答案是:Eclipse是通过配置文件来“认知”一个工程的。而这些配置文件,都是一些隐藏文件。你新建一个Maven工程,其实是按照模板写好了这些配置文件,所以Eclipse才能读出来这个工程的相关信息。

(一)我们先看一个普通的J2SE工程的配置文件的内容和其效果,工程如下:

1,.settings文件夹下的那个文件:org.eclipse.jdt.core.prefs。里面的内容是:

  1. eclipse.preferences.version=1
  2. org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
  3. org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
  4. org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
  5. org.eclipse.jdt.core.compiler.compliance=1.8
  6. org.eclipse.jdt.core.compiler.debug.lineNumber=generate
  7. org.eclipse.jdt.core.compiler.debug.localVariable=generate
  8. org.eclipse.jdt.core.compiler.debug.sourceFile=generate
  9. org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
  10. org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
  11. org.eclipse.jdt.core.compiler.source=1.8

很明显,是明确jdk的,还有一些编译器的参数的配置。

2,.classpath。这个隐藏文件的内容是:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <classpath>
  3. <classpathentry kind="src" path="src" />
  4. <classpathentry kind="con"
  5. path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" />
  6. <classpathentry kind="output" path="bin" />
  7. </classpath>

这个比较重要,因为这个文件直接控制了一个工程的目录结构。kind属性为src,表示这个文件夹是放源码的文件夹,物理位置在/src。也就是我们看到的那个文件夹。

kind属性为con,也就是config,里面控制的是这个工程的JVM,JDK,等等信息,一把来说我们不需要的修改。kind属性为output,说明了编译后产生的class文件放在物理地址:/bin里面。

看到这个文件的配置,我们就知道前面为什么工程的目录安排是那样的了,换句话说,正是这个文件的配置,工程才体现那样的目录。再进一步说,如果你在这个文件里面按照你的想法配置,那么你保存之后,项目的目录结构会自动变成你安排的那样。

3,.project。内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <projectDescription>
  3. <name>MyProject</name>
  4. <comment></comment>
  5. <projects>
  6. </projects>
  7. <buildSpec>
  8. <buildCommand>
  9. <name>org.eclipse.jdt.core.javabuilder</name>
  10. <arguments>
  11. </arguments>
  12. </buildCommand>
  13. </buildSpec>
  14. <natures>
  15. <nature>org.eclipse.jdt.core.javanature</nature>
  16. </natures>
  17. </projectDescription>

也是一些关于编译的配置文件,下面讲Maven还会讲到。

以上是一个普通java工程的所有文件和其目录结构,可以看到在我之前编写代码时没仔细注意的地方,一些配置文件对工程的结构做出了约束。

(二)接下来是一个Maven工程。

在Package Explorer里面看到的目录结构是:

几个不同点:  

  1. Source Folder不是一个简单的src,而是src/main/java

因为Maven是一种强约束的工程类型。它对工程的文件命名和格式要求比较严格。其好处是指定了规范,方便代码的移植和理解。上文中的src/main/java是个什么呢?其实是一个路径,打开其物理地址会发现,是一个src文件夹包含了一个main文件夹,再包含了java文件夹。这样的层次的文件路径一共有4个,如下:

  • src/main/java  :这个目录下储存主要的java代码
  • src/main/resources  :储存主要的资源文件。比如spring的xml配置文件和log4j的properties文件。
  • src/test/java  :储存测试用的类,比如JUNIT的测试一般就放在这个目录下面
  • src/test/resources  :储存测试用的资源文件

  当然,这4个不是都必须有。前两个一般都有,后两个可能没有(不需要测试)。

  与之类似的,如果一个包的名字是com.jd.MyProject,那么它在硬盘上的目录结构就是com/jd/MyProject。

  2.  有一个target文件夹

很简单,就是源码编译后生成的class文件放的地方(如果是一个WEB应用,还有别的信息也在编译打包之后放在target里面)。具体放的时候也会根据是工程代码还是测试代码区分放置class文件。

  3. 一个pom.xml。这个文件可以说是一个Maven工程最重要的文件了,因为这个是Maven的基础配置文件,和程序员打交道最多的也在这个文件里面,包括配置依赖关系等等。

根据上文描述,我们都知道了Eclispe里面的.开头的隐藏文件真正配置了工程的目录结构等等。那么这个Maven工程的配置文件里面写的是什么呢?

1,.settings:是Maven工程的一些配置,比如JDK版本和文件编码格式(UTF-8),比如父工程和子Module的依赖关系。

2,.classpath,这个文件内容变化了:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <classpath>
  3. <classpathentry kind="src" output="target/classes" path="src/main/java">
  4. <attributes>
  5. <attribute name="optional" value="true" />
  6. <attribute name="maven.pomderived" value="true" />
  7. </attributes>
  8. </classpathentry>
  9. <classpathentry kind="src" output="target/test-classes"
  10. path="src/test/java">
  11. <attributes>
  12. <attribute name="optional" value="true" />
  13. <attribute name="maven.pomderived" value="true" />
  14. </attributes>
  15. </classpathentry>
  16. <classpathentry kind="con"
  17. path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
  18. <attributes>
  19. <attribute name="maven.pomderived" value="true" />
  20. </attributes>
  21. </classpathentry>
  22. <classpathentry kind="con"
  23. path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
  24. <attributes>
  25. <attribute name="maven.pomderived" value="true" />
  26. </attributes>
  27. </classpathentry>
  28. <classpathentry kind="output" path="target/classes" />
  29. </classpath>

之前我们知道了一个Maven工程目录结构什么样子,这里就可以看出来为什么这个样子。正是这个文件的配置,让工程在Eclipse里面体现出来了与之前不一样的目录结构。具体一点就是它重新规定了各种文件(源码,配置,输出)在工程中存放的目录。事实上,你在Eclipse里面做工程目录的修改的核心都是修改这文件,从而体现你的修改。

3,.project.xml

这个文件可以说是很重要的,因为一开始我思考的问题是:怎么样把一个普通的JavaSE工程变成一个Maven工程的答案就在这里。我一点点修改,终于发现了最关键的一点,也就在这个文件里面。文件内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <projectDescription>
  3. <name>MavenDemo</name>
  4. <comment></comment>
  5. <projects>
  6. </projects>
  7. <buildSpec>
  8. <buildCommand>
  9. <name>org.eclipse.jdt.core.javabuilder</name>
  10. <arguments>
  11. </arguments>
  12. </buildCommand>
  13. <buildCommand>
  14. <name>org.eclipse.m2e.core.maven2Builder</name>
  15. <arguments>
  16. </arguments>
  17. </buildCommand>
  18. </buildSpec>
  19. <natures>
  20. <nature>org.eclipse.jdt.core.javanature</nature>
  21. <nature>org.eclipse.m2e.core.maven2Nature</nature>
  22. </natures>
  23. </projectDescription>

可以看到多了两行。一个在buildCommand标签里面,一个在natures标签里面。如果你在一个普通的JavaSE工程里面加入了

  1. <nature>org.eclipse.m2e.core.maven2Nature</nature>

可以看到Eclipse就会在工程图标上加上一个M,认定其是一个Maven工程。删除这句话再保存,前面多出来的那句话也会自动删除。说明这句话正是确定这个工程“特性”的关键。

这个特性本身不重要,重要的是终于明白了,看上去很简单的东西,别人究竟是怎么实现的。在平常觉得理所当然的操作-->结果的背后,也许就体现了别人设计的智慧。比如这里:通过文件记录工程的目录结构。

以上就是Maven和普通工程的一些工程结构上的区别,以及造成这些区别的原因。

Eclipse中一个Maven工程的目录结构 (MacOS)的更多相关文章

  1. Eclipse中一个Maven工程的目录结构

    在之前的javaSE开发中,没有很关注Eclipse工程目录下的环境,总是看见一个src就点进去新建一个包再写一个class.以后的日子中也没有机会注意到一个工程到底是怎么组织的这种问题,跟不要说自己 ...

  2. 第一个Maven工程的目录结构和文件内容及联网问题

    [第一个Maven工程] ①目录结构 Hello |---src |---|---main |---|---|---java |---|---|---resources |---|---test |- ...

  3. Idea中新建maven项目的目录结构

    maven项目的目录结构如下所示 pom.xml文件内容如下所示 <?xml version="1.0" encoding="UTF-8"?> &l ...

  4. 在eclipse中的maven工程中执行maven命令的步骤

    执行maven命令的步骤: 1.找到maven工程的pom.xml文件,点中右键 2.在弹出的对话框中选择run as 3.在弹出的对话框中输入compile 再执行即可

  5. 在Eclipse中建立Maven工程

  6. Maven学习(一) -- 安装Maven及Eclipse中配置Maven

    标签(空格分隔): 学习笔记 本文环境:Windows7, JDK1.7.0_76 安装及配置Maven环境变量 需要电脑中已经有Java环境 在控制台中输入:echo %JAVA_HOME%看是否能 ...

  7. 【Maven】eclipse中使用Maven、生命周期

    1.在eclipse中创建maven工程 >>在eclipse中配置maven: 配置maven版本:Eclips自带了一个maven,一般不用自带的这个,而选择我们安装的那个maven ...

  8. Eclipse中创建Maven多模块工程

    1.先创建父项目 在Eclipse里面New -> Maven Project: 在弹出界面中选择“Create a simple project” 这样,我们就按常规模版创建了一个Maven工 ...

  9. 转:Eclipse中创建Maven版的Web工程(详解)

    一.搭建步骤 ♦首先创建一个Maven的Project,如下图: ♦点击Next,勾选 Create a simple project ♦点击Next,注意Packing要选择war,因为我们创建的是 ...

随机推荐

  1. MySQL存储引擎MyISAM与InnoDB

    一. MySQL存储引擎MyISAM与InnoDB如何选择 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...

  2. CRC32为例详细解析(菜鸟至老鸟进阶)

    CRC-知识解析 cyclic redundancy check 写在前面的话: 之前在做学校项目的时候用到了CRC 原理,但在网上查找的过程中,发现讲解CRC知识的资源很多,但是对新手比较友好的.讲 ...

  3. HDU 1084 What Is Your Grade?(排序)

    题目在这里:1084 题目描述: “Point, point, life of student!” This is a ballad(歌谣)well known in colleges, and yo ...

  4. SAP 文本框实例

    SAP 文本框 简单实例 REPORT ZTEST001. DATA: OK_CODE LIKE SY-UCOMM, SAVE_OK LIKE SY-UCOMM. DATA: REF_EDIT_CTN ...

  5. JQuery实现子级选择器

    效果图如下: HTML代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  6. 记一次微信小程序在安卓的白屏问题

    在做小程序的时候,做到了一个限时商品售卖,用到了倒计时,因为这个原因导致了安卓手机上使用小程序时,将小程序放入后台运行一段时间后,再次进入小程序后出现了页面白屏或者点击事件失效的情况,这里记录下 1. ...

  7. Javascript简单特效及摘要

    1.js中的Element对象 ** var input1=docuemnt.getElementById("input1"); //alert(input1.value); // ...

  8. 关于IT人的一些消遣区

    https://www.csdn.net/http://www.51cto.com/http://bestcbooks.com/http://www.jobbole.com/http://www.co ...

  9. 裸机——wdt

    1. 首先晓得看门狗的基本知识 看门狗是带复位功能的定时器,用于在系统跑飞时复位系统. 接下来按照上次的知识对看门狗进行推导 看门狗的关键词是 定时器 复位 定时器 关键是 时间段 中断 时间段 关键 ...

  10. 硬件中断--DEBUG系列

    问题描述: 在线调试时,全速运行,程序进入硬件中断,查看堆栈窗口,发现是从A函数进去的.但是A函数应该没有问题的: 再次重复,发现是从B函数进去的,但是B函数之前运行起来也没有问题的,而且没有传入参数 ...