1. 为何写这篇文章java
在以前的javaSE开发中,没有很关注Eclipse工程目录下的环境,老是看见一个src就点进去新建一个包再写一个class。之后的日子中也没有机会注意到一个工程究竟是怎么组织的这种问题,更不要说本身试试怎么控制了。程序员
可是最近在学习Maven的时候知道了它对工程的目录结构有要求,也就是所谓的“惯例优于配置”。有一个被绝大多数人承认的java工程的目录结构被肯定下来。这样统一了市面上各类复杂配置的工程。因而我便从新开始查资料,看看别人到底如何安排一个优秀的工程框架的。spring
同时,我也分析了Eclipse会给一个项目生成什么配置文件,其中的内容和意义又是什么.这样能内心面大体有个数,本地的什么文件是干什么的,怎么来的。框架
2. 一个简单的J2SE工程目录结构eclipse
首先,Mac中,一个默认的Eclipse工程的目录结构:maven
看上去就这么多?其实不是的,在个人mac环境下,通常时候Eclipse左边的目录是Package Explorer,也是是如上图显示的内容。可是其实能够用另一个显示其真正的目录,也就是包含一些隐藏文件。叫Navigator(事实上Package Explorer默认隐藏Linux系统下的以.开头的隐藏文件,因此看不见,而Navigator默认打开)。显示效果以下:工具
3. 为何Eclipse能认出来这些?学习
那么除了这些以外,其实还有值得探究的部分:测试
这些问题能够提出不少,其实本质上都是:Eclipse是一个集成开发环境,而Maven是一种项目管理及自动构建工具(维基百科),Eclipse没有责任去“识别”Maven。这句话乍一听感受和直觉不相符合:明明新建工程的时候选择新建一个Maven工程,Eclipse就知道这是一个Maven工程啊?明明导入一个Maven工程,Eclipse就能正确识别打开啊?ui
实际上是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个,以下:
固然,这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工程里面加入了
<nature>org.eclipse.m2e.core.maven2Nature</nature>
能够看到Eclipse就会在工程图标上加上一个M,认定其是一个Maven工程。删除这句话再保存,前面多出来的那句话也会自动删除。说明这句话正是肯定这个工程“特性”的关键。
这个特性自己不重要,重要的是终于明白了,看上去很简单的东西,别人到底是怎么实现的。在日常以为理所固然的操做-->结果的背后,也许就体现了别人设计的智慧。好比这里:经过文件记录工程的目录结构。
以上就是Maven和普通工程的一些工程结构上的区别,以及形成这些区别的缘由。