Maven實戰與原理分析(二):maven實戰

 

學Maven,這篇萬餘字的教程,真的夠用了!

1 Maven 介紹

1.1 爲什麼使用 Maven

由於 Java 的生態非常豐富,無論你想實現什麼功能,都能找到對應的工具類,這些工具類都是以 jar 包的形式出現的,例如 Spring,SpringMVC、MyBatis、數據庫驅動,等等,都是以 jar 包的形式出現的,jar 包之間會有關聯,在使用一個依賴之前,還需要確定這個依賴所依賴的其他依賴,所以,當項目比較大的時候,依賴管理會變得非常麻煩臃腫,這是 Maven 解決的第一個問題。

Maven 還可以處理多模塊項目。簡單的項目,單模塊分包處理即可,如果項目比較複雜,要做成多模塊項目,例如一個電商項目有訂單模塊、會員模塊、商品模塊、支付模塊...,一般來說,多模塊項目,每一個模塊無法獨立運行,要多個模塊合在一起,項目纔可以運行,這個時候,藉助 Maven 工具,可以實現項目的一鍵打包。

Maven 之前,我們更多的是使用 Ant 的項目構建工具,Ant 有一個特點,每次都得寫,每次都寫的差不多,配置也臃腫。所以,後來搞出來 Maven。Maven 就是最先進的版本構建工具嗎?不是的,只不過,目前在 Java 領域 Maven 使用比較多。除了 Maven,還有 Gradle。

1.2 Maven 是什麼

Maven 是一個項目管理工具,它包含了一個項目對象模型(Project Object Model),反映在配置中,就是一個 pom.xml 文件。是一組標準集合,一個項目的生命週期、一個依賴管理系統,另外還包括定義在項目生命週期階段的插件(plugin)以及目標(goal)。

當我們使用 Maven 的使用,通過一個自定義的項目對象模型,pom.xml 來詳細描述我們自己的項目。

Maven 中的有兩大核心:

  • 依賴管理:對 jar 的統一管理(Maven 提供了一個 Maven 的中央倉庫,mvnrepository.com/,當我們在項目中添加完… 會自動去中央倉庫下載相關的依賴,並且解決依賴的依賴問題)
  • 項目構建:對項目進行編譯、測試、打包、部署、上傳到私服等

2. Maven 安裝

  • Maven 是 Java 項目,因此必須先安裝 JDK。

下載 Maven:

  • 下載 Maven

下載地址:maven.apache.org/download.cg…

  • 解壓並配置

配置,只需要配置環境變量即可:

首先配置 MAVEN_HOME:

然後配置環境變量:

  • 檢驗安裝

如果使用了 IntelliJ IDEA ,可以不用去額外下載 Maven,直接使用 IDEA 中自帶的 Maven 插件即可。IntelliJ IDEA 中自帶的 Maven 插件在 \ideaIU-2019.2.4.win\plugins\maven\lib\maven3

3. Maven 配置

實際上,沒有特殊需求的話,安裝好之後直接就可以用了。一般來說,還是需要稍微配置一下,比如中央倉庫的問題。默認使用 Maven 自己的中央倉庫,使用起來網速比較慢,這個時候,可以通過修改配置文件,將倉庫改成國內的鏡像倉庫,國內倉庫使用較多的是阿里巴巴的倉庫。

3.1 倉庫類型

倉庫類型 說明
本地倉庫 就是你自己電腦上的倉庫,每個人電腦上都有一個倉庫,默認位置在 當前用戶名\.m2\repository
私服倉庫 一般來說是公司內部搭建的 Maven 私服,處於局域網中,訪問速度較快,這個倉庫中存放的 jar 一般就是公司內部自己開發的 jar
中央倉庫 有 Apache 團隊來維護,包含了大部分的 jar,早期不包含 Oracle 數據庫驅動,從 2019 年 8 月開始,包含了 Oracle 驅動

現在存在 3 個倉庫,那麼 jar 包如何查找呢?

3.2 本地倉庫配置

本地倉庫默認位置在 當前用戶名\.m2\repository,這個位置可以自定義,但是不建議大家自定義這個地址,有幾個原因:

  1. 雖然所有的本地的 jar 都放在這個倉庫中,但是並不會佔用很大的空間。
  2. 默認的位置比較隱蔽,不容易碰到

技術上來說,當然是可以自定義本地倉庫位置的,在 conf/settings.xml 中自定義本地倉庫位置:

3.3 遠程鏡像配置

由於默認的中央倉庫下載較慢,因此,也可以將遠程倉庫地址改爲阿里巴巴的倉庫地址:

<mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
複製代碼

這段配置,加在 settings.xml 中的 mirrors 節點中:

4. Maven 常用命令

Maven 中有一些常見的命令,如果使用 Eclipse 需要手動敲命令,如果使用 IDEA 的話,可以不用命令,直接點點點就可以了。

常用命令 中文含義 說明
mvn clean 清理 這個命令可以用來清理已經編譯好的文件
mvn compile 編譯 將 Java 代碼編譯成 Class 文件
mvn test 測試 項目測試
mvn package 打包 根據用戶的配置,將項目打成 jar 包或者 war 包
mvn install 安裝 手動向本地倉庫安裝一個 jar
mvn deploy 上傳 將 jar 上傳到私服

這裏需要注意的是,這些命令都不是獨立運行的,它有一個順序。舉個簡單例子:

我想將 jar 上傳到私服,那麼就要構建 jar,就需要執行 package 命令,要打包,當然也需要測試,那就要走 mvn test 命令,要測試就要先編譯.....,因此,最終所有的命令都會執行一遍。不過,開發者也可以手動配置不執行某一個命令,這就是跳過。一般來是,除了測試,其他步驟都不建議跳過。

當然,如果開發者使用了 IDEA ,這些命令不用手動敲,點一下就行:

4.1 通過命令來構建項目

可以直接通過命令來構建一個 Maven 項目,不過在實際開發中,一般使用 Eclipse 或者 IDEA 就可以直接創建 Maven 項目了。

創建命令:

mvn archetype:generate -DgroupId=org.javaboy -DartifactId=firstapp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
複製代碼

看到如下提示,表示項目創建成功:

項目創建成功後,就兩個文件:

說明對一個任何一個項目而言,最最核心的就是這兩個。

pom.xml 中,則定義了所有的項目配置。

4.2 對項目進行打包

接下來,我們通過 mvn package 命令可以將剛剛創建的項目打成一個 jar 包。

在打包之前,需要配置 JDK 的版本至少爲 7 以上,因此,我們還需要手動修改一下 pom.xml 文件,即添加如下配置:

添加完成後,執行打包命令,注意執行所有命令時,命令行要定位到 pom.xml 文件所在的目錄,看到如下提示,表示項目打包成功。

4.3 將項目安裝到本地倉庫

如果需要將項目安裝到本地倉庫,可以直接執行 mvn install 命令,注意,mvn install 命令會包含上面的 mvn package 過程。

安裝到本地倉庫之後,這個時候,點開自己的本地倉庫,就可以看到相關的 jar 了。

5. IDEA 中使用 Maven

不同於 Eclipse,IDEA 安裝完成後,就可以直接使用 Maven 了。

5.1 Maven 相關配置

IDEA 中,Maven 的配置在 File->Settings->Build,Execution,Deployment->Build Tools->Maven:

5.2 JavaSE 工程創建

首先在創建一個工程時,選擇 Maven 工程:

如果勾選上 Create from archetype ,則表示可以根據一個項目骨架(項目模板)來創建一個新的工程,不過,如果只是創建 JavaSE 項目,則不用選擇項目骨架。直接 Next 即可。然後填入項目的座標,即 groupId 和 artifactId。

填完之後,直接 Next 即可。這樣,我們就會獲取一個 JavaSE 工程,項目結構和你用命令創建出來的項目一模一樣。

5.3 JavaWeb 工程創建

在 IDEA 中,創建 Maven Web 項目,有兩種思路:

  • 首先創建一個 JavaSE 項目,然後手動將 JavaSE 項目改造成一個 JavaWeb 項目
  • 創建項目時選擇項目骨架,骨架就選擇 webapp

兩種方式中,推薦使用第一種方式。

5.3.1 改造 JavaSE 項目

這種方式,首先創建一個 JavaSE 項目,創建步驟和上面的一致。

項目創建完成後,首先修改 pom.xml ,配置項目的打包格式爲 war 包。 這樣,IDEA 就知道當前項目是一個 Web 項目:

然後,選中 JavaSE 工程,右鍵單擊,選擇 Open Module Settings,或者直接按 F4,然後選擇 Web,如下圖:

接下來,在 webapp 目錄中,添加 web.xml 文件。

注意,一定要修改 web.xml 文件位置:

配置完成後,點擊 OK 退出。

項目創建完成後,接下來就是部署了。

部署,首先點擊 IDEA 右上角的 Edit Configurations:

然後,配置 Tomcat:

接下來選擇 Deployment 選項卡,配置要發佈的項目:

最後,點擊 IDEA 右上角的三角符號,啓動項目。

5.3.2 通過 webapp 骨架直接創建

這種方式比較簡單,基本上不需要額外的配置,項目創建完成後,就是一個 web 項目。只需要我們在創建項目時,選擇 webapp 骨架即可。

選擇骨架之後,後面的步驟和前文一致。

項目創建成功後,只有 webapp 目錄,這個時候,自己手動創建 java 和 resources 目錄,創建完成後,右鍵單擊,選擇 Mark Directory As,將 java 目錄標記爲 sources root,將 resources 目錄標記爲 resources root 即可。

凡是在 IDEA 右下角看到了 Enable Auto Import 按鈕,一定點一下

6. Maven 依賴管理

Maven 項目,如果需要使用第三方的控件,都是通過依賴管理來完成的。這裏用到的一個東西就是 pom.xml 文件,概念叫做項目對象模型(POM,Project Object Model),我們在 pom.xml 中定義了 Maven 項目的形式,所以,pom.xml 相當於是 Maven 項目的一個地圖。就類似於 web.xml 文件用來描述三大 web 組件一樣。

這個地圖中都涉及到哪些東西呢?

6.1 Maven 座標

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    junit
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
</dependencies>
複製代碼

  • dependencies

在 dependencies 標籤中,添加項目需要的 jar 所對應的 maven 座標。

  • dependency

一個 dependency 標籤表示一個座標

  • groupId

團體、公司、組織機構等等的唯一標識。團體標識的約定是它以創建這個項目的組織名稱的逆向域名(例如 org.javaboy)開頭。一個 Maven 座標必須要包含 groupId。一些典型的 groupId 如 apache 的 groupId 是 org.apache.

  • artifactId

artifactId 相當於在一個組織中項目的唯一標識符。

  • version

一個項目的版本。一個項目的話,可能會有多個版本。如果是正在開發的項目,我們可以給版本號加上一個 SNAPSHOT,表示這是一個快照版(新建項目的默認版本號就是快照版)

  • scope

表示依賴範圍。

我們添加了很多依賴,但是不同依賴的使用範圍是不一樣的。最典型的有兩個,一個是數據庫驅動,另一個是單元測試。

數據庫驅動,在使用的過程中,我們自己寫代碼,寫的是 JDBC 代碼,只有在項目運行時,才需要執行 MySQL 驅動中的代碼。所以,MySQL 驅動這個依賴在添加到項目中之後,可以設置它的 scope 爲 runtime,編譯的時候不生效。

單元測試,只在測試的時候生效,所以可以設置它的 scope 爲 test,這樣,當項目打包發佈時,單元測試的依賴就不會跟着發佈。

6.2 依賴衝突

  • 依賴衝突產生的原因

在圖中,a.jar 依賴 b.jar,同時 a.jar 依賴 d.jar,這個時候,a 和 b、d 的關係是直接依賴的關係,a 和 c 的關係是間接依賴的關係。

6.2.1 衝突解決

  1. 先定義先使用
  2. 路徑最近原則(直接聲明使用)

以 spring-context 爲例,下圖中 x 表示失效的依賴(優先級低的依賴,即路徑近的依賴優先使用):

上面這兩條是默認行爲。

我們也可以手動控制。手動控制主要是通過排除依賴來實現,如下:

<dependency>
    <groupId>org.springframework</groupId>
    spring-context
    <version>5.1.9.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            spring-core
        </exclusion>
    </exclusions>
</dependency>
複製代碼

這個表示從 spring-context 中排除 spring-core 依賴。

7. Maven 私服

Maven 倉庫管理也叫 Maven 私服或者代理倉庫。使用 Maven 私服有兩個目的:

  1. 私服是一個介於開發者和遠程倉庫之間的代理
  2. 私服可以用來部署公司自己的 jar

7.1 Nexus 介紹

Nexus 是一個強大的 Maven 倉庫管理工具,使用 Nexus 可以方便的管理內部倉庫同時簡化外部倉庫的訪問。官網是:www.sonatype.com/

7.2 安裝

  • 下載

下載地址:www.sonatype.com/download-os…

  • 解壓

將下載下來的壓縮包,拷貝到一個沒有中文的路徑下,然後解壓。

  • 啓動

解壓之後,打開 cmd 窗口(以管理員身份打開 cmd 窗口),然後定位了 nexus 解壓目錄,執行 nexus.exe/run 命令啓動服務。

這個啓動稍微有點慢,大概有 1 兩分鐘的樣子

啓動成功後,瀏覽器輸入 http://lcoalhost:8081 打開管理頁面。

打開管理頁面後,點擊右上角上的登錄按鈕進行登錄,默認的用戶名/密碼是 admin/admin123。當然,用戶也可以點擊設置按鈕,手動配置其他用戶。

點擊 Repositories 可以查看倉庫詳細信息:

7.2.1 倉庫類型

名稱 說明
proxy 表示這個倉庫是一個遠程倉庫的代理,最典型的就是代理 Maven 中央倉庫
hosted 宿主倉庫,公司自己開發的一些 jar 存放在宿主倉庫中,以及一些在 Maven 中央倉庫上沒有的 jar
group 倉庫組,包含代理倉庫和宿主倉庫
virtual 虛擬倉庫

7.2.2 上傳 jar

上傳 jar,配置兩個地方:

  • Maven 的 conf/settings.xml 文件配置:
<server>
  <id>releases</id>
  <username>admin</username>
  <password>admin123</password>
</server>
<server>
  <id>snapshots</id>
  <username>admin</username>
  <password>admin123</password>
</server>
複製代碼

在要上傳 jar 的項目的 pom.xml 文件中,配置上傳路徑:

<distributionManagement>
    <repository>
        <id>releases</id>
        <url>http://localhost:8081/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>snapshots</id>
        <url>http://localhost:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>
複製代碼

配置完成後,點擊 deploy 按鈕,或者執行 mvn deploy 命令就可以將 jar 上傳到私服上。

7.2.3 下載私服上的 jar

直接在項目中添加依賴,添加完成後,額外增加私服地址即可:

<repositories>
    <repository>
        <id>local-repository</id>
        <url>http://localhost:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>
複製代碼

8. 聚合工程

所謂的聚合工程,實際上也就是多模塊項目。在一個比較大的互聯網項目中,項目需要拆分成多個模塊進行開發,比如訂單模塊、VIP 模塊、支付模塊、內容管理模塊、CMS、CRM 等等。這種拆分方式,實際上更接近於微服務的思想。在一個模塊中,還可以繼續進行拆分,例如分成 dao、service、controller 等。

有人可能會說,這個分包不就行了嗎?

小項目當然可以分包,大項目就沒法分包了。比如,在一個大的電商系統中,有一個子模塊叫做用戶管理、還有一個子模塊叫做訂單管理,這兩個子模塊都涉及到用戶,像這種情況,我們就需要將用戶類單獨提取出來,做成單獨的模塊,供其他模塊調用。

8.1 多模塊項目展示

|--javaboy-parent
      |-- javaboy-cms
      |-- javaboy-crm
      |-- javaboy-manger
           |-- javaboy-manager-model
           |-- javaboy-manager-dao
           |-- javaboy-manager-service
           |-- javaboy-manager-web
複製代碼

以 javaboy-manger 爲例,javaboy-manager 本身並不提供功能,它只負責管理他自己的子模塊,而他的子模塊每一個都無法獨立運行,需要四個結合在一起,纔可以運行。項目打包時,model、dao、service 都將打包成 jar,然後會自動將打包好的 jar 複製到 web 中,再自動將 web 打包成 war 包。

8.2 IDEA 中創建聚合工程

1.創建一個空的 Maven 項目:

項目創建完成後,由於 parent 並不參與業務的實現,只是用來管理它的子模塊,因此,src 目錄可以將其刪除。

2.選中當前工程,右鍵單擊,New->Module

然後繼續選擇創建一個 Maven 項目:

在 IDEA 中,已經默認指明瞭當前 Module 的 parent,開發者只需要填入當前 Module 的 artifactId 即可:

javaboy-manager 創建完成後,此時,觀察 javaboy-parent 的 pom.xml 文件,發現它自動加上了 packing 屬性:

其中,它的 packaging 屬性值爲 pom,這表示它是一個聚合工程,同時,他還多了 modules 節點,指明瞭它自己的子模塊。 同時,注意 javaboy-manager ,它自身多了一個 parent 節點,這個 parent 節點描述了它的父模塊的屬性值:

<parent>
    javaboy-parent
    <groupId>org.javaboy</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
複製代碼

這個 parent 不僅僅是一個簡單的父子關係描述,它存在繼承關係,一般我們可以在 parent 中統一定義依賴或者插件的版本號

3.由於 javaboy-manager 本身也是一個聚合工程,因此,javaboy-manager 的 src 目錄也可以刪除。

4.選中 javaboy-manager,右鍵單擊,New->Module 創建一個新的 Maven 模塊出來。這個步驟類似於第二步,不在贅述。 這裏,新的 javaboy-manager-model 創建成功後,我們手動配置它的 packaging 屬性值爲 jar。

5.依照第 4 步,再分別創建 javaboy-manager-service 以及 javaboy-manager-dao 6.繼續創建 javaboy-manager-web 模塊,不同於其他模塊,web 模塊需要打包成 war。web 模塊創建可以參考【第五篇文章】。 7.web 工程創建完成後,完善模塊之間的繼承關係。

javaboy-manager-web 依賴 javaboy-manager-service javaboy-manager-service 依賴 javaboy-manager-dao javaboy-manager-dao 依賴 javaboy-manager-model

注意,依賴默認是有傳遞性的,即在 javaboy-manager-dao 中依賴了 javaboy-manager-model,在 javaboy-manager-service 也能訪問到。

配置後的依賴關係如下圖:

接下來就可以在不同的模塊中寫代碼,然後進行項目部署了。部署方式參考【第五篇文章】

有一個需要注意的地方,在多模塊項目中,web 項目打包需要注意以下問題:

  1. 不可以直接單獨打包
  2. 如果要打包,有兩種方式:
  • 第一種就是先手動挨個將 model、dao、service 安裝到本地倉庫
  • 從聚合工程處打包,即從 web 的parent 處打包。

​ 微信公衆號【程序員黃小斜】作者是前螞蟻金服Java工程師,專注分享Java技術乾貨和求職成長心得,不限於BAT面試,算法、計算機基礎、數據庫、分佈式、spring全家桶、微服務、高併發、JVM、Docker容器,ELK、大數據等。關注後回覆【book】領取精選20本Java面試必備精品電子書。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章