在之前的javaSE开发中,没有很关注Eclipse工程目录下的环境,总是看见一个src就点进去新建一个包再写一个class。以后的日子中也没有机会注意到一个工程到底是怎么组织的这种问题,跟不要说自己试试怎么控制了。
但是最近在学习Maven的时候知道了它对工程的目录结构有要求,也就是所谓的“惯例优于配置”。有一个被绝大多数人认可的java工程的目录结构被确定下来。这样统一了市面上各种复杂配置的工程。于是我便重新开始查资料,看看别人到底如何安排一个优秀的工程框架的。
首先,一个默认的Eclipse工程的目录结构:
MyProject:工程的名字
src:一个源文件文件夹,官方说法:“source folder on build path”。里面最多放的是源码,在javaSE里面,经常就是把包直接放在src目录下。
com.jd.MyProject:一个包。一般是倒写的域名保证其独一无二性。
Main.java:一个java文件。
看上去就这么多?其实不是的,在我的mac环境下,一般时候Eclipse左边的目录是Package Explorer,也是是如上图显示的内容。但是其实可以用另外一个显示其真正的目录,也就是包含一些隐藏文件。叫Navigator。显示效果如下:
由此可见,如果包的名字通过.连接,其在物理储存上产生的效果就是产生层次文件夹,com.jd.MyProject---->com/jd/MyProject。
那个bin目录是存放编译后的class文件的地方,当然一般Eclispe每一次保存都会自动编译,程序员一般不用太管它编译的结果,所以在最常用的Package Explorer里面不会显示这个bin文件夹。
其次还多了一些文件。
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里面看到的目录结构是:
仔细看一下这个目录结构,和最普通的JavaSE还是不一样。首先其源码文件夹有两个:src/main/java和 src/test/java。说明在src文件夹下,有main和test两个分支。简单来说,main是工厂主体,包括各种源码资源之类的,而test里面包含了测试代码和资源。原因是测试代码确实不需要被打包发布。而两个文件夹里面的包,依然还是像之前一样根据倒写域名的命名规范来命名。
几个不同点:
1,有一个target文件夹,很简单,就是源码编译后生成的class文件放的地方。具体放的时候也会根据是工程代码还是测试代码区分放置class文件。
2,一个pom.xml。这个文件可以说是一个Maven工程最重要的文件了,因为这个是Maven的基础配置文件,和程序员打交道最多的也在这个文件里面,包括配置依赖关系等等。
再来看看Navigator下的文件结构:
其中一些文件比较重复如:src/test和target/test-classes就不打开了。
以下是变化:
1,.settings,这个我就没有很认真的研究了,可以猜一下多出的部分是Maven的一些配置,比如JDK版本和文件编码格式(UTF-8)等等。
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>
之前说过这个文件是用来配置工程的目录结构的,可以看到正是这个文件的配置,让工程在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和普通工程的一些工程结构上的区别。