本文將詳述 maven 在軟件項目中的使用。首先講述 maven 的基本工作原理及環境的搭建。然后講述開發及配置管理人員如何使用 maven,最后將介紹 maven 與 eclipse 集成使用。
maven 原理
maven 是人為制訂的一套開發規范,該規范定義了開發一個 java 項目時的各個細節。maven 通過 pom.xml 這一配置文件來描述一個項目。以下將介紹 pom.xml 文件及 maven 的主要概念。
pom.xml
POM (Project Object Model) 是對一個項目定義的模型。通過該配置文件可以完整地定義一個項目所涉及的如:項目放在哪里,項目依賴哪些東西,項目的作者是誰,項目如何構建等信息。maven 將通過該文件定義的信息對項目進行構建。
以下是 POM 文件的概要(詳細內容參考:http://maven.apache.org/pom.html):
<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>...</groupId> <!-- 項目所在組、機構 --> <artifactId>...</artifactId> <!-- 項目產品名稱 --> <version>...</version> <!-- 項目產品版本 --> <packaging>...</packaging> <!-- 項目包類型 --> <dependencies>...</dependencies> <!-- 項目依賴包 --> <parent>...</parent> <!-- 項目所繼承的父項目 --> <dependencyManagement>...</dependencyManagement> <!-- 繼承父系的依賴 --> <modules>...</modules> <!-- 所包含的子模塊 --> <properties>...</properties> <!-- 定義變量 --> <!-- 項目構建設置 --> <build>...</build> <!-- 項目報告生成設置 --> <reporting>...</reporting> <!-- 項目更多設置 --> <name>...</name> <!-- 項目名稱 --> <description>...</description> <!-- 項目描述 --> <url>...</url> <!-- 項目網站 --> <inceptionYear>...</inceptionYear> <!-- 項目起始年份 --> <licenses>...</licenses> <!-- 項目許可 --> <organization>...</organization> <!-- 項目組織 --> <developers>...</developers> <!-- 項目開發人員 --> <contributors>...</contributors> <!-- 項目貢獻者 --> <!-- 環境設置 --> <issueManagement>...</issueManagement> <!-- 問題管理 --> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <!-- 代碼管理 --> <prerequisites>...</prerequisites> <repositories>...</repositories> <!-- 指定依賴包所在的倉庫 --> <pluginRepositories>...</pluginRepositories> <!-- 指定插件所在的倉庫 --> <distributionManagement>...</distributionManagement> <!-- 指定發布位置 --> <profiles>...</profiles> <!-- 針對不同的環境使用不同的配置,如開發與生產環境的數據庫是不同的 --> </project>
從概要可以看到 maven 可以做代碼管理,代碼測試報告,項目網站,項目依賴關系等管理。
maven 運作
sample | pom.xml 項目定義文件 \---src 項目源文件 +---main 項目主文件 \---test 項目測試文件
一個 maven 項目的目錄結構如上所示,maven 通過項目定義文件(pom.xml)來對項目的源文件進行操作。源文件包含兩部分,一部分是最終能夠提供功能的主要文件(main),另一部分是用於測試主要功能的輔助文件(test)。
maven 程序的整個操作就是根據項目定義文件中的定義對源文件進行操作。maven 在 components.xml 文件中定義了一個項目的三種生命周期。每種生命周期有不同的階段((詳細參考 http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference))。
maven 的每個生命周期定義了不同的階段,每個階段都可以設置該階段所使用的插件及插件中的任務。以下通過 maven 命令來舉例說明:
# 將項目設置到默認生命周期的 deploy 階段 # 這將使源碼已經被編譯、測試、安裝及發布 mvn deploy # 直接通過 maven 運行 clean 插件的 clean 任務 mvn clean:clean # 先將項目設置到清理生命周期(clean) # 然后將項目設置到默認生命周期的編譯階段(compile) # 最后運行 jetty 插件的 run 任務 mvn clean compile jetty:run
通過下面的配置(取自 components.xml )可以了解到一個生命周期是如何定義的,並且生命周期的每個階段會執行哪些 plugin 的任務。
<component> <role>org.apache.maven.lifecycle.Lifecycle</role> <implementation>org.apache.maven.lifecycle.Lifecycle</implementation> <role-hint>site</role-hint> <configuration> <id>site</id> <phases><!-- site 生命周期包括哪些階段 --> <phase>pre-site</phase> <phase>site</phase> <phase>post-site</phase> <phase>site-deploy</phase> </phases> <default-phases> <site><!-- site 階段使用 site-plugin 的 site 任務 --> org.apache.maven.plugins:maven-site-plugin:2.0.1:site </site> <site-deploy> org.apache.maven.plugins:maven-site-plugin:2.0.1:deploy </site-deploy> </default-phases> </configuration> </component>
maven 網絡結構
maven 會將所有的公共 jar 包放置於公共的中心倉庫(Center Repository)中。為了提高速度,各個網站會復制一份中心倉庫的內容並且與中心倉庫保持同步。這些復制的倉庫稱為鏡像(Mirror)。在本地的電腦上,會有一個本地倉庫,maven 根據項目的依賴關系從中心倉庫或者鏡像中下載所需要的 jar 包到本地倉庫中,供不同的項目使用。
maven 環境搭建
maven 搭建
maven 安裝
- 通過 http://maven.apache.org/download.html 下載 apache-maven-3.0.3-bin.zip
- 本地解壓,設置 JAVA_HOME 及 PATH 保證 mvn 命令能夠運行
maven 測試
新建一個測試目錄,在命令行中進入該目錄,運行:
mvn archetype:generate
此時,會看到 maven 下載了很多東西到機器上來,最終會顯示一個列表,並提示輸入
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 163:
這是要用戶選擇創建什么類型的項目,maven 會根據選擇將項目的基本框架搭建好。由於是為了測試 maven 這里可以直接選擇默認的項目(直接按回車),接下來會提示輸入
Choose version: 1: 1.0-alpha-1 2: 1.0-alpha-2 3: 1.0-alpha-3 4: 1.0-alpha-4 5: 1.0 6: 1.1 Choose a number: 6:
這是讓用戶選擇版本,同樣選擇默認的版本(回車),接下來提示
Define value for property 'groupId': :
這是讓用戶輸入所在的組織,可以輸入如 com.mycompany 或者 org.mygroup 等,這里輸入本站的網址:
Define value for property 'groupId': : com.lsi2
之后提示輸入產出物的名稱,后面類似:
Define value for property 'artifactId': : sample Define value for property 'version': 1.0-SNAPSHOT: : Define value for property 'package': : : com.lsi2.sample Confirm properties configuration: groupId: com.lsi2 artifactId: sample version: 1.0-SNAPSHOT package: com.lsi2.ssa Y: : y
以上步取可以通過一條命令搞定:
mvn archetype:generate -DgroupId=com.lsi2.sample -DartifactId=sample -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
這樣項目就創建完成,可以運行以下命令來測試項目
cd sample mvn test
看到以下內容,說明 maven 安裝成功
------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.lsi2.sample.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.778s [INFO] Finished at: Sat Dec 31 01:59:43 CST 2011 [INFO] Final Memory: 8M/20M [INFO] ------------------------------------------------------------------------
maven 配置
maven 配置包括以下三個層面:
- Global (MAVEN_HOME/conf/settings.xml) 針對所有用戶的配置
- User (USER_HOME/.m2/settings.xml) 針對單個用戶的配置
- Project (PROJECT_ROOT/pom.xml) 針對單個項目的配置
對於單個項目的配置前文已有介紹(pom.xml)。現介紹 settings.xml((詳細內容可以參考 http://maven.apache.org/settings.html))。
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository/> <!-- 指定本地倉庫位置 --> <interactiveMode/> <!-- 指定 maven 的運行模式是否為交互模式 --> <usePluginRegistry/> <!-- 目前少用,指定插件配置文件 --> <offline/> <!-- 指定是否為離線模式,在不需要網絡交互的時候使用 --> <pluginGroups/> <!-- 指定插件所在的路徑,maven 將通過該路徑查找插件 --> <servers/> <!-- 指定服務器的用戶名、密碼等,用於上傳,下載文件等 --> <mirrors/> <!-- 指定 maven 主倉庫的鏡像 --> <proxies/> <!-- 網絡代理配置,用於有代理的網絡 --> <profiles/> <!-- pom.xml 中的 profile 能夠用於公共配置的部分 --> <activeProfiles/> </settings>
nexus 搭建
默認情況下,maven 通過客戶端機器直接與中心倉庫進行網絡通信,會存在以下兩個主要的問題:
- 網絡下載速度慢,團隊使用 maven 時,帶寬占用大。
- 直接進行網絡通信,會暴露內部的一些信息,安全性降低。
為此,可以通過搭建一個代理服務器來解決以上問題。搭建代理服務器后的網絡結構為:
搭建代理服務器之后,可以將開發成品(jar包)容上傳到代理服務器上,並使用代理服務器來管理所有的團隊共用 jar 包。
目前有兩種流行的代理服務器:http://www.jfrog.com/products.php|artifactory 和 http://nexus.sonatype.org/|nexus。以下介紹 nexus 的安裝配置。
nexus 安裝
- 從 http://nexus.sonatype.org/download-nexus.html 下載 nexus 到本地
- 解壓 nexus
- 設置好 JAVA_HOME 及 PATH
- 運行 nexus\nexus-oss-webapp-1.9.2.3\bin\jsw\windows-x86-32((win32目錄,其它環境的目錄類同))\nexus.bat
nexus 測試
安裝完成之后,可以訪問以下網址:
http://localhost:8081/nexus/
初始的用戶名及密碼:
admin/admin123 用於管理系統 deployment/deployment123 用於發布jar包
基於 nexus 的 maven 配置
settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <servers> <server> <!-- 設置發布 jar 包時的用戶名及密碼 --> <id>deploymentRepo</id> <username>deployment</username> <password>deployment123</password> </server> </servers> ... <mirrors> <mirror> <!-- 設置 maven 的遠程倉庫為 nexus --> <id>nexus</id> <mirrorOf>*</mirrorOf> <name>Local Repository</name> <url>http://192.168.1.60:8081/nexus/content/groups/public</url> </mirror> </mirrors> ... <profiles> ... <profile> <!-- 設置 nexus 的路徑等 --> <id>nexus</id> <repositories> <repository> <id>central</id> <name>local private nexus</name> <url>http://localhost:8081/nexus/content/groups/public</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>central</id> <name>local private nexus</name> <url>http://localhost:8081/nexus/content/groups/public</url> <releases><enabled>true</enabled></releases> <snapshots><enabled>true</enabled></snapshots> </pluginRepository> </pluginRepositories> </profile> ... </profiles> ... <activeProfiles> <!-- 激活 nexus --> <activeProfile>nexus</activeProfile> </activeProfiles> ... </settings>
pom.xml
<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/maven-v4_0_0.xsd"> ... <distributionManagement> <!-- 設置發布 jar 包時所用到的 server 及路徑 --> <repository> <id>deploymentRepo</id> <!-- 與 settings.xml 中的 server id 對應 --> <name>Uploadable Nexus Repo</name> <url>http://192.168.1.60:8081/nexus/content/repositories/snapshots/</url> </repository> </distributionManagement> ... </project>
maven 使用
以上介紹完 maven 的基本原理及相關配置,接下來舉例說明 maven 的使用。
設置編譯環境
在 pom.xml 中設置如下:
<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/maven-v4_0_0.xsd"> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.5</source> <target>1.5</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> ... </project>
使用 eclipse
運行
mvn eclipse:eclipse
如果需要在 eclipse 中能夠查看到依賴包的源碼,可以配置 eclipse 插件如下:
<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/maven-v4_0_0.xsd"> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.8</version> <configuration> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> </configuration> </plugin> </plugins> </build> ... </project>
使用 jetty 插件
jetty 可以進行熱部署,在開發時可以不用頻繁啟動服務,從而提高開發效率。使用 jetty 的配置如下:
<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/maven-v4_0_0.xsd"> ... <build> <plugins> <plugin> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.10</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <stopKey>foo</stopKey> <stopPort>9999</stopPort> <webDefaultXml>src/test/resources/webdefault.xml</webDefaultXml> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>run</goal> </goals> <configuration> <scanIntervalSeconds>0</scanIntervalSeconds> <daemon>true</daemon> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </project>
同時,還需要修改 jetty 的配置文件 webdefault.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="true" version="2.5"> ... <servlet> <servlet-name>default</servlet-name> <servlet-class>org.mortbay.jetty.servlet.DefaultServlet</servlet-class> ... <init-param> <param-name>useFileMappedBuffer</param-name> <param-value>false</param-value> <!-- 不緩存文件,文件修改之后馬上使用新文件 --> </init-param> ... </servlet> ... </web-app>
該文件可以從 jetty 插件中找到,修改后可以放置於以下目錄中,在測試時使用。
src/test/resources
清除所有編譯的內容
運行下列命令,可以清除所有已經編譯的產出。
mvn clean:clean