《Maven實戰》筆記

maven是什麼

maven是html

  • 構建工具
  • 依賴關係工具
  • 項目信息管理工具

而JAVA世界的ant只是一個構建工具,不具有依賴管理的功能,須要配合使用ivy進行依賴管理。java

maven的安裝

下載maven,配置環境變量。
升級的技巧:使用符號連接,環境變量指向符號連接,升級的時候修改符號連接便可。web

maven使用入門

手動搭建maven項目

  • 編寫pom
  • 編寫主代碼和測試代碼

使用ArcheType建立maven項目骨架

命令以下
mvn archetype:generate
實際上上述命令的完整格式是:
mvn groupId:artifactId:version:goal
即運行的是archetype插件的generate目標。
也能夠爲本身的項目開發archetype。apache

編譯,測試,打包,安裝,運行

  • 編譯: mvn clean compile
  • 測試:mvn clean test
  • 打包:mvn clean package
  • 安裝:mvn clean install
  • 運行
    • 使用maven-shade-plugin插件生成可執行的jar.
      • pom中配置shade插件。
      • 執行 mvn clean install,從新生成jar包。
    • 運行jar包。java -jar xxx.jar

座標和依賴

maven座標的各個元素

  • groupId
  • artifactId
  • version
  • packaging:打包方式。好比jar或者war。
  • classifier:附屬構件。好比javadoc和源代碼。

依賴的元素

  • groupId
  • artifactId
  • version
  • type:同坐標中的packaging。默認爲jar。
  • scope:依賴範圍
  • optional
  • exclusions

依賴範圍

三種classpath:編譯classpath,測試classpath,運行classpath。tomcat

  • compile:對編譯、測試、運行三種classpath都有效。
  • test:只對測試classpath有效。好比JUnit。
  • provided:編譯和測試classpath有效,運行classpath無效。好比servlet API。
  • runtime:測試和運行classpath有效,編譯classpath無效。好比JDBC驅動實現。
  • system:與provided一致。只是這種狀況必須顯示指定依賴文件的路徑,這樣就和本機系統綁定了,使得構建不具備移植性,慎用。
  • import:不會對三種classpath產生影響。

依賴範圍不只能夠控制依賴與三種classpath的關係,還對傳遞性依賴產生影響。網絡

傳遞性依賴

傳遞性依賴機制:maven會解析各個直接依賴的pom,將那些必要的間接依賴以傳遞性依賴的形式引入到當前項目中。(咱們只須要關心項目的直接依賴)eclipse

maven會自動解析全部項目的直接依賴和傳遞性依賴,確保每一個構件只有惟一的版本在依賴中存在。最後解析後的這些依賴被稱爲已解析依賴
相關命令
查看已解析依賴:mvn dependency:list
依賴樹:mvn dependency:tree
分析依賴:mvn dependency:analyzemaven

生命週期和插件

生命週期和階段

maven對構建過程進行了抽象,被稱爲生命週期。生命週期自己不作具體任務,實際的任務由插件完成。這是一種模板方法模式。ide

生命週期包含一些階段(phase),這些階段有先後依賴關係,後面的階段依賴前面的階段。能夠定義多個生命週期,生命週期之間彼此是獨立的,不存在依賴關係。工具

Maven擁有三套獨立的生命週期,分別是clean、default和site。

  • clean生命週期的目的是清理項目。
  • default生命週期的目的是構建項目。
  • site生命週期的目的是創建項目站點。

clean生命週期

包含三個階段:

  • pre-clean
  • clean
  • post-clean

defalut生命週期

包含的階段太多,詳情 Introduction to the Build Lifecycle

site生命週期

  • pre-site
  • site
  • post-site
  • site-deploy

命令行與生命週期的關係

經常使用的mvn clean compile命令實際上調用的是clean生命週期的clean階段和default生命週期的compile階段。

插件和插件目標

對於插件而言,爲了可以複用代碼,它可以執行多個任務,實現多個功能,這些功能彙集在一個插件裏,每一個功能就是一個插件目標。好比maven-dependency-plugin插件,它能夠分析項目依賴,列出項目的依賴樹,找出無用依賴。

一般寫法是:插件:插件目標

插件綁定

將生命週期中的階段和插件目標綁定。
那麼在命令行輸入生命週期的階段,則對應的插件目標就會執行相應的任務。

Q:是否能夠直接在命令行中直接指定執行某個插件目標'???
A:能夠。

多個插件目標能夠綁定到同一個階段。

總結

A Build Lifecycle is Made Up of Phases
A Build Phase is Made Up of Plugin Goals

聚合和繼承

聚合

解決以下需求:想要用一條命令一次性構建多個項目(模塊)。
這就是maven聚合(多模塊)特性。
方法:增長一個聚合模塊,其中的pom.xml中的packaging爲pom。

聚合模塊和其餘模塊的目錄關係

不必定是父子關係,也能夠是平行的目錄結構。

繼承

目的:解決多模塊maven項目的配置重複問題。
方法:增長一個父模塊,在父pom中聲明一些配置供子pom繼承。

父模塊和聚合模塊通常同時存在多模塊maven項目中。父模塊也要在聚合模塊中的modules標籤中配置。

可繼承的pom元素

  • groupId
  • version
  • dependencies
  • dependencyManagement
  • build
  • repositories
  • properties
  • ...

依賴管理

能夠將一些依賴放到父模塊的dependencies元素中,這樣子類就無需配置了。但會存在一個問題:全部的子模塊都會依賴父模塊dependencies元素中聲明的依賴,即便一些子模塊並不須要這些依賴。

解決方法:
在父模塊中使用dependencyManagement元素聲明依賴,這些依賴不爲直接被子模塊繼承。子模塊若要繼承父模塊dependencyManagement中聲明的某個依賴的話,則須要在子模塊中的dependencies元素中從新聲明(只須要配置groupId和artifactId便可)。
雖然這種方式不會大幅度的減小配置,可是因爲在父模塊的pom中統一申明瞭依賴的版本,能夠避免在子模塊中使用的依賴版本不一致的狀況。

import依賴範圍

名爲import的依賴範圍只在dependencyManagement元素下采用效果。其做用是將目標pom中的dependencyManagement配置導入併合併到當前pom中的dependencyManagement元素中。

插件管理

pluginManagement和dependencyManagement相似。

聚合與繼承的關係

目的不一樣:

  • 聚合是爲了方便快速構建項目。
  • 繼承是爲了消除重複配置。

聚合模塊 vs. 被聚合模塊:聚合模塊知道被聚合模塊,但被聚合模塊不知道聚合模塊的存在。
父模塊 vs. 子模塊:父模塊不知道那些子模塊繼承自它,但子模塊都知道本身的父模塊。

相同點:父模塊和聚合模塊都沒有實際內容,而且二者的pom中的packaging都必須是pom。

實際項目中,會發現一個pom既是父pom,又是聚合pom,這麼作主要是爲了方便。

約定優於配置

全部的pom都繼承自超級POM。
對於Maven3,超級POM在$MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路徑下。
對於Maven2,超級POM在$MAVEN_HOME/lib/maven-model-x.x.x-uber.jar中的org/apache/maven/pom-4.0.0.xml路徑下。
在超級POM中已經定義了源代碼的路徑、構建的輸出路徑等信息。

反應堆

構建一個多模塊項目時,因爲模塊間存在繼承或者聚合關係,模塊間的構建是有前後關係的,總體構成一個有向無環圖DAG。反應堆就是全部模塊組成的一個構建結構。

持續集成

好比TensorFlow的持續集成:http://ci.tensorflow.org/

使用maven構建web應用

war文件的目錄結構

todo

web項目的maven目錄結構

todo

快速生成web項目的maven目錄結構

生成web項目的maven目錄結構

jetty-maven-plugin插件

doc

<plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>8.1.13.v20130916</version> <configuration> <webApp> <contextPath>/</contextPath> </webApp> <connectors> <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector"> <port>8081</port> <maxIdleTime>60000</maxIdleTime> </connector> </connectors> </configuration> </plugin>

http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

使用cargo實現自動化部署

Cargo支持兩種本地部署的方式:standalone模式和existing模式。以下是standalone模式:

<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.6.2</version> <configuration> <container> <containerId>tomcat8x</containerId> <home>D:\Program Files\apache-tomcat-8.0.23</home> </container> <configuration> <type>standalone</type> <home>${project.build.directory}/tomcat8x</home> <properties> <cargo.servlet.port>8181</cargo.servlet.port> </properties> </configuration> </configuration> </plugin>

existing模式:

<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.6.2</version> <configuration> <container> <containerId>tomcat8x</containerId> <home>D:\Program Files\apache-tomcat-8.0.23</home> </container> <configuration> <type>existing</type> <home>D:\Program Files\apache-tomcat-8.0.23</home> <!-- existing模式下好像沒法更改端口 --> <!--<properties>--> <!--<cargo.servlet.port>8080</cargo.servlet.port>--> <!--</properties>--> </configuration> </configuration> </plugin>

Archetype

Archetype Catalog

mvn archetype:generate卡住的問題

緣由:
執行命令mvn archetype:generate時,maven-archetype-plugin插件會先尋找archetype-catalog.xml文件,默認是從中央庫中尋找該文件。因爲中央庫訪問比較慢,因此出現卡頓現象。

解決方案:

  • 方案(1):加上archetypeCatalog參數
    mvn archetype:generate -DarchetypeCatalog=internal

  • 方案(2):配置一個國內的鏡像,加速對archetype-catalog.xml的訪問。好比阿里雲的maven鏡像,以下:

    <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>

經驗:安裝maven後必定要配置一個國內的中央庫鏡像,好比阿里maven中央鏡像庫。由於後續不少mvn命令須要下載不少插件和依賴,網絡很差容易致使操做失敗。

阿里雲maven庫列表

下載單個構建的源碼和文檔

mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:sources mvn dependency:get -Dartifact=com.alibaba.citrus:citrus-webx-all:3.2.4:jar:javadoc
相關文章
相關標籤/搜索