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和普通工程的一些工程結構上的區別,以及形成這些區別的緣由。