1:pom.xml
Maven項目的核心文件,非常重要。POM(Project Object Model)項目對象模型,其定義了項目的基本信息,用於描述項目如何構建,聲明項目依賴等等。
創建一個最簡單的pom文件:pom.xml,首先新建文件夾HelloWorld,在裏面新建一個pom。xml,然後新建一個包(src/main/java),在新建一個包com.soulprayer.maven.maven_study,然後進入該文件夾,打開pom.xml文件(推薦使用Notepad++ / Sublime),並輸入下列代碼清單中的內容:
pom.xml代碼清單
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.soulprayer.maven</groupId> <artifactId>maven-study</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>Maven Hello World Project</name> </project>
- 第一行是XML頭,指定該xml文檔的版本和編碼方式
- <project></project>所有pom.xml的根元素,聲明瞭一些pom相關的命名空間及xsd元素約束。
- <modelVersion></modelVersion> 指定了當前POM模型的版本,對於Maven2一級Maven3來說,只能是4.0.0
- <groupId></groupId>定義了項目屬於哪個組,這個組往往和項目所在的組織或公司存在關聯
- <artifactId></artifactId>定義了當前Maven項目在組中唯一的ID,
- <version></version>定義了當前Maven項目的版本
- <name> 定義了當前項目更加友好清晰的名稱
備註:groupId、artifactId、version 三者共同確定唯一座標,也就是說這個項目在整個Maven倉庫中是唯一的.
優點:
它能讓項目對象模型最大程度地與實際代碼相獨立,即解耦或者正交性。這在很大程度上避免了Java代碼和POM代碼相互影響,比如當項目需要升級版本時,只需要修改POM,而不需要修改Java代碼,而在POM穩定之後,日常的Java代碼開發工作基本不涉及POM的修改。
2:編寫主代碼
項目主代碼和測試代碼不同,項目的主代碼會被打包到最終的構件中(如jar),而測試代碼只在測試時用到,不會被打包。默認情況下,Maven項目的主代碼位於/src/main/java目錄中,我們遵循Maven的約定,創建該目錄,然後在該目錄下創建文件 com/soulprayer/maven/maven-study/HelloWorld.java。
代碼清單如下:
package main.java.com.soulprayer.maven.maven_study; public class HelloWorld { public String sayHello() { return "Hello Maven"; } public static void main(String[] args) { System.out.println(new HelloWorld().sayHello()); } }
這是一個很簡單的Java類,它有一個sayHello()方法,返回一個String,同時還有一個Main方法,創建一個HelloWorld實例,調用sayHello()方法,並將結果輸出到控制檯上。
關於該Java代碼有三點需要注意:
- 應該把項目主代碼放到src/main/java目錄下(約定大於配置),這樣就不需要額外的配置,Maven會自動搜索該目錄找到項目主代碼
- 該Java類的報名是com.soulprayer.maven,這與之前在POM中定義的groupId和artifaceId相吻合。一般來說,項目中的Java類的包都應該基於項目的groupId和artifactId,這樣更加清晰,也更加符合邏輯。
- pom.xml的位置很重要,不要亂放,要放到和src平級的目錄下,這樣groupId纔會生效,否則又會多一層。
代碼編寫完畢及滿足上述條件後,在項目根目錄下運行命令mvn cleam compile 會得到如圖所示的輸出結果。
clean會先告訴Maven清理輸出目錄 target/,compile告訴Maven編譯項目主代碼,從輸出中看到Maven首先執行了clean:clean任務,刪除 target/目錄。默認情況下,Maven構建的輸出都在target/目錄中,接着執行resources:resources任務(未定義項目資源,略過),最後執行compiler:compile任務,將項目主代碼編譯至target/classes目錄。
3:編寫測試代碼
爲了使項目結構保持清晰,主代碼與測試代碼應該分開來放,放置於獨立目錄中,主代碼的目錄是/src/main/java,則對應的測試代碼的目錄是/src/test/java,因此,在編寫測試用例之前,要先創建該目錄,然後爲其添加Junit依賴,本文使用Junit進行測試。
修改的POM的代碼清單如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.soulprayer.maven</groupId> <artifactId>maven_study</artifactId> <version>1.0-SNAPSHOT</version> <name>Maven Hello World Project</name> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> </dependencies> </project>
新增元素說明
- <dependencies></dependencies>在該元素下可以包含多個<dependency>元素以聲明項目的依賴,這裏就通過groupId、artifactId、version三個元素定義了唯一的junit依賴標識。然後Maven會依據conf/setting.xml中的配置去中央倉庫進行下載。
- <scope></scope>依賴範圍:test表示該依賴只對測試有效,換句話說,測試代碼中import Junit代碼是沒問題的,但是如果在主代碼中用import Junit代碼,就會造成編譯錯誤,如果不聲明依賴範圍,默認的就是compile,表示對主代碼和測試代碼都生效。
編寫測試類 HelloWorldTest.java,代碼清單:
package test.java.com.soulprayer.maven.maven_study;
import org.junit.Test import static org.junit.Assert.assertEquals;
public class HelloWorldTest { @Test public void testSayHello(){ HelloWorld helloWorld = new HelloWorld(); String result = helloWorld.sayHello(); assetEquals("Hello Maven",result); } }
一個典型的單元測試包含三個步驟:
- 準備測試類及數據
- 執行要測試的行爲
- 檢查結果
使用Maven執行測試
可以看到,Tests run(測試運行)1個,Failures(失敗):0,Error(錯誤)0,Skipped(跳過):0
4:打包和運行
將項目進行編譯、測試之後,下一個重要步驟就是打包(package)。HelloWorld的POM中沒有指定打包類型,使用默認打包類型jar,簡單地執行命令mvn clean package進行打包,可以看到如下輸出:
實際上jar插件的jar目標將項目主代碼打包成一個名爲maven_study-1.0-SNAPSHOT.jar的文件。該文件也位於target/輸出目錄中,它是根據artifact-version.jar規則進行命名的。還可以使用finalName來自定義該文件的名稱,這個會在後面說。
進行到這裏,我們得到了項目的輸出,一個jar文件,如果有需要的話,就可以複製這個jar文件到其他項目的Classpath中從而使用HelloWorld類。但是,如何才能讓其他的maven項目直接引用這個jar呢,這裏需要一個安裝的步驟,執行mvn clean instal,效果圖如下:
在打包之後,又執行了安裝任務install。從輸出中的紅框中可以看到,該任務將項目的jar安裝到了本地Maven倉庫中,可以打開相應的文件查看到HelloWorld項目的pom和jar。之前的Junit的pom和jar也是同樣的道理,只有構件被下載到本地倉庫之後,才能由Maven項目所使用。
到目前爲止,都沒有運行HelloWorld項目,在HelloWorld中是存在一個main方法的。默認打包生成jar是不能夠直接運行的,因爲帶有main方法的類信息不會添加到manifest中(打開jar文件的 META-INF / MANIFEST.MF文件,將無法看到Main-Class一行)。爲了能夠生成可執行的jar文件,需要藉助maven-shade-plugin,錯誤圖與插件配置如下:
插件配置代碼清單:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.soulprayer.maven.maven_study.HelloWorld</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
代碼清單說明:
- <build></build>:構建需要相關插件
- <plugins></plugins>:同<dependencies></dependencies>,在該標籤下可以包含多個<plugin>
- <plugin></plugin>:具體插件,同<dependency>,利用其中的三者確定插件唯一標識。
- <executions></executions>:同<dependencies></dependencies>,其標籤下可以包含多個<execution>運行規則,我們指定了<phase>階段爲package的運行規則爲實現了org.apache.maven.plugins.shade.resource.ManifestResourceTransformer這個接口將會把指定類:com.soulprayer.maven.maven_study.HelloWorld,作爲程序入口類,並將其放入到程序清單中。
執行效果圖