超詳細Maven技術應用指南

Ziph發表於2020-06-18

該文章,GitHub已收錄,歡迎老闆們前來Star!

GitHub地址: https://github.com/Ziphtracks/JavaLearningmanual

搜尋關注微信公眾號“碼出Offer”,送你學習福利資源!


一、前言

在我們的專案資源中,你會發現需要匯入的jar包越來越多,讓jar包的管理越來越沉重。它會表現為以下幾個缺點:

  • 每個專案都需要手動蒐集和匯入所需要的jar包
  • 專案中用到的jar包有版本更新,我們需要重新蒐集並匯入到專案中
  • 相同的jar包匯入到不同的專案中,jar包會在本地儲存多份

針對上述問題,我們就需要使用統一的管理工具:Maven

二、瞭解Maven

2.1 什麼是Maven

Maven是一個基於專案物件模型(POM)的概念的純Java開發的開源的專案管理工具。主要用來管理Java專案,進行依賴管理(jar包依賴管理)和專案構建(專案編譯、打包、測試、部署)。此外還能分模組開發,提高開發效率。

2.2 Maven的下載安裝

關於Maven的下載,我們需要下載它的解壓包。

Maven下載地址: https://us.mirrors.quenda.co/apache/maven/maven-3/3.6.3/binaries/

image-20200616171323409
image-20200616171323409

下載後將Maven解壓到目錄中就可以了!

注意: 解壓的目錄與tomact伺服器的形式是一樣的,不要有中文及特殊符號!

image-20200616171637526
image-20200616171637526

2.3 Maven目錄結構解析

目錄名稱 描述
bin 儲存mvn的各種可執行檔案
boot 含有plexus-classworlds類載入器框架,Maven 使用該框架載入自己的類庫
conf 存放settings.xml等配置檔案
lib 儲存Maven執行時所需要的Java類庫
LICENSE/NOTICE/README.txt 針對Maven的版本、第三方軟體等簡要介紹

2.4 配置環境變數

Maven依賴Java環境的配置環境,所以要確保jdk版本在1.7以上,maven版本在3.3以上。

  • 配置環境變數與jdk環境變數配置是一樣的,在本機中建立MAVEN_HOME環境變數,並將maven的解壓路徑設定進去,點選確定(路徑參考上圖解壓後的結果圖路徑)
  • 修改path環境變數,新增%MAVEN_HOME%\bin後,一路點選確定即可!

2.5 測試

下載解壓、配置環境變數後,我們開啟DOS命令視窗,鍵入mvn -v檢視maven版本資訊

  • 如果看到如下圖片maven的版本資訊,證明maven安裝配置成功!
  • 在Maven的版本資訊你就可以得知它依賴於jdk環境!
image-20200616172931556
image-20200616172931556

2.6 Maven專案模型圖

三、Maven的配置

3.1 配置本地倉庫

本地倉庫簡單來說,就是在本地的maven中儲存管理所需jar包

  1. 首先,開啟maven目錄conf資料夾中的settings.xml配置檔案

  2. 其次,找到標號1的那一行配置資訊,並複製此配置資訊放在其下面

  3. 然後,在磁碟中建立一個目錄,作為儲存jar檔案的本地倉庫

  4. 最後,將複製的此配置資訊路徑替換成自己建立的本地倉庫目錄路徑,參考標號2的操作

image-20200616174928266
image-20200616174928266

3.2 配置jdk

3.2.1 全域性配置

由於Maven依賴於jdk環境,所以我們也需要在maven中配置jdk(我使用的jdk是主流的1.8版本)

  1. 開啟settings.xml配置檔案,找到<profiles>標籤,你會發現標籤內都是註釋的內容,我們需要在標籤內,寫入自己的jdk的配置資訊。配置如下:
  2. 在maven中新增好jdk的配置資訊後,我們需要在</profiles>結束標籤後新增<activeProfiles>標籤內容,讓配置好的<profiles>標籤中內容生效

注意: profile標籤中的id是此配置資訊的名稱,在後面使用activeProfile標籤讓其配置生效的時候,需要保證id與activeProfile的名稱一致!(貼圖供大家參考!)

    <!-- 配置jdk -->
    <profile>
        <id>jdk1.8</id>
        <activation>
            <activeByDefault>true</activeByDefault>    
            <jdk>1.8</jdk>    
        </activation>    
        <properties>    
            <maven.compiler.source>1.8</maven.compiler.source>    
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> 
        </properties>    
    </profile>
<!-- 使配置好的profiles標籤中內容生效 -->
<activeProfiles>
    <activeProfile>jdk1.8</activeProfile>
</activeProfiles>
image-20200616181057029
image-20200616181057029
3.2.2 單個專案修改

後面我們會了解到maven專案是通過pom.xml進行構建資訊配置和依賴資訊配置。其中就包括配置編譯需要的jdk版本。所以我們直接修改pom檔案就可以實現單個專案修改,但是我們並不推薦此種方式,因為這個方式需要每個專案都要修改,不具有可重用性!

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
</build>

四、倉庫

4.1 倉庫概念

  • 儲存依賴的地方,體現形式就是本地的一個目錄。
  • 倉庫中不僅存放依賴,而且管理著每個依賴的唯一標識(座標),Java專案憑座標獲取依賴。

4.2 倉庫分類

Maven倉庫可以分為本地倉庫和遠端倉庫,其中遠端倉庫又分為中央倉庫、公共倉庫和私服

  • 本地倉庫: 本地倉庫存放著專案中所需jar檔案
  • 中央倉庫: Maven的中央倉庫是由Maven社群提供儲存jar檔案的倉庫
  • 公共倉庫: 國內廠家提供的儲存jar檔案的倉庫,比如:aliyun倉庫
  • 私服: 由公司建立的儲存jar檔案的倉庫,可在公司範圍內共享,不對外開放

當專案中需要jar檔案依賴時,會從倉庫中查詢獲取,如果我們把所有倉庫都配置好。maven在查詢獲取依賴的時候遵循一個依賴查詢順序,如下:(如果本地倉庫找不到依賴就去私服下載,以此類推……)

依賴查詢順序: 本地倉庫 - > 私服 - > 公共倉庫 - > 中央倉庫

image-20200616184606968
image-20200616184606968

4.3 本地倉庫

本地倉庫: 本地目錄中存放所需jar包,需修改settings配置檔案來配置本地倉庫

  • 使用過的依賴都會儲存在本地倉庫中,實現複用

4.4 遠端倉庫

4.4.1 中央倉庫

中央倉庫: Maven中央倉庫是由Maven社群提供的倉庫,不用任何配置,maven中內建了中央倉庫地址。其中就包含絕大多數流行的開源Java構件

4.4.2 公共倉庫

公共倉庫: 第三方維護的jar檔案倉庫,比如阿里雲提供的倉庫。但是jar檔案可能不如官方的中央倉庫全,有時候也會找不到,所以如果專案構建不成功,可以更改映象為官方的,下載完jar包再去改回來

  • aliyun倉庫地址:http://maven.aliyun.com/nexus/content/groups/public/

  • 因為Maven社群提供的中央倉庫在國外,國內使用下載依賴速度過慢,所以一般我們都配置國內的公共倉庫來代替中央倉庫

  • 使用時,需要在settings.xml配置檔案中新增配置資訊。開啟settings.xml配置檔案,找到<mirrors>標籤,你也會發現這是一個空標籤,最後標籤內填寫如下配置就OK!

    <!--setting.xml中新增如下配置-->
    <mirror>
        <id>aliyun</id>  
        <!-- 中心倉庫的 mirror(映象) -->
        <mirrorOf>central</mirrorOf>    
        <name>Nexus aliyun</name>
        <!-- aliyun倉庫地址 以後所有要指向中心倉庫的請求,都會指向aliyun倉庫-->
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>  
    </mirror>
image-20200616223651045
image-20200616223651045
4.4.3 私服

私服: 公司建立儲存jar檔案的倉庫,只對公司範圍共享,不對外開放。可以通過Nexus來建立、管理一個私服。

4.4.3.1 私服概念
  • 私服是架設在區域網的一種特殊的遠端倉庫,目的是代理遠端倉庫及部署第三方構件。

  • 有了私服之後,當 Maven 需要下載依賴時,直接請求私服,私服上存在則下載到本地倉庫;否則,私服請求外部的遠端倉庫,將構件下載到私服,再提供給本地倉庫下載。

  • 私服可以解決在企業做開發時每次需要的jar包都要在中心倉庫下載,且每次下載完只能被自己使用,不能被其他開發人員使用

  • 所謂私服就是一個伺服器,但是不是本地層面的,是公司層面的,公司中所有的開發人員都在使用同一個私服

4.4.3.2 私服架構

我們可以使用專門的 Maven 倉庫管理軟體來搭建私服,比如:Apache ArchivaArtifactorySonatype Nexus。這裡我們使用Sonatype Nexus

  • 我們可以在圖中得到在無私服的情況下,我們都需要從遠端倉庫去獲取jar檔案並儲存在本地倉庫,由於中央倉庫是國外的,所以下載速度比較慢等等原因,並存在很多缺點,比如我們公司內使用
  • 我們在圖中可清晰的看到,如果有私服的話,我們需要從私服中,查詢jar檔案,如果私服沒有該jar檔案,就需要去中央倉庫或公共倉庫去下載,然後傳到私服中,最後傳入到自己的本地倉庫進行使用。假設公司員工再一次使用到該jar檔案,它會先從私服中找有沒有這個jar檔案,由於我們之前的員工已經將該jar檔案儲存到了私服中,所以就省去了其他員工呼叫遠端倉庫的步驟。並且私服是公司內部區域網型別的,下載速度會比遠端倉庫快出很多倍
無私服 有私服
私服1
私服1
私服2
私服2
4.4.3.3 Nexus安裝(瞭解即可)

下載我們需要下載Zip解壓包即可,將解壓包解壓到本地碟符中即可!

解壓後,你會看到nexus目錄為私服目錄,sonatype-work目錄中包含儲存私服下載的依賴。

4.4.3.4 Nexus登入

訪問私服:http://localhost:8081/nexus/

登入私服的賬號為admin,密碼為admin123

4.4.3.5 倉庫列表
倉庫型別 描述
group 包含多個倉庫,通過group庫的地址可以從包含的多個倉庫中查詢構件
hosted 私服 伺服器本地的倉庫,其中儲存諸多構件
proxy 代理倉庫,其會關聯一個遠端倉庫, 比如中央倉庫,aliyun倉庫,向該倉庫查詢構件時,如果沒有會從其關聯的倉庫中下載
倉庫名 描述
Releases 存放專案的穩定釋出版本,一個模組做完後如果需要共享給他人,可以上傳到私服的該庫
Snapshots 對應不穩定的釋出版本
3rd party 存放中央倉庫沒有的 ,如ojdbc.jar,可以上傳到私服的該庫中
倉庫列表
私服_list
私服_list
4.4.3.6 倉庫組

而此時就有問題,私服中有很多倉庫,每個倉庫都有自己的url,則專案中配置哪個倉庫呢 ?

私服中有一個倉庫組,組中包含多個倉庫,可以指定倉庫組的url,即可從多個倉庫中獲取構件

關於倉庫的設定: 由於我們在使用私服的時候,本地倉庫沒有的jar檔案,需要去私服找,私服沒有的話,就去中央倉庫找。所以我們需要把私服內的中央倉庫換為阿里雲倉庫,這樣可以保證我們國內的下載速度。

倉庫組 注意:proxy的倉庫排序在最後
私服_deploy2
私服_deploy2
4.4.3.7 手動上傳倉庫
4.4.3.8 Maven關聯私服

配置settings.xml,設定私服地址、認證等資訊(關聯私服需要新增配置檔案資訊如下,找到父標籤,新增子標籤內容即可)

<servers>
    <server> 
        <id>nexus-public</id> <!-- nexus的認證id -->
        <username>admin</username> <!--nexus中的使用者名稱密碼-->
        <password>admin123</password> 
    </server>
</servers>
<profiles>
    <profile> 
        <id>nexus</id> 
        <repositories> 
            <repository> 
                <id>nexus-public</id> <!--nexus認證id 【此處的repository的id要和 <server>的id保持一致】-->
                <!--name隨便-->
                <name>Nexus Release Snapshot Repository</name> 
                <!--地址是nexus中倉庫組對應的地址-->
                <url>http://localhost:8081/nexus/content/groups/public/</url>
                <releases><enabled>true</enabled></releases> 
                <snapshots><enabled>true</enabled></snapshots> 
            </repository>
        </repositories> 
        <pluginRepositories> <!--外掛倉庫地址,各節點的含義和上面是一樣的-->
            <pluginRepository> 
                <id>nexus-public</id> <!--nexus認證id 【此處的repository的id要和 <server>的id保持一致】-->
                <!--地址是nexus中倉庫組對應的地址-->
                <url>http://localhost:8081/nexus/content/groups/public/</url>
                <releases><enabled>true</enabled></releases> 
                <snapshots><enabled>true</enabled></snapshots> 
            </pluginRepository> 
        </pluginRepositories> 
    </profile>
</profiles>
<activeProfiles>
    <activeProfile>yourjdk</activeProfile>
    <!-- 使私服配置生效 -->
    <activeProfile>nexus</activeProfile>
</activeProfiles>
4.4.3.9 Meven專案部署到私服
  • 執行mvn deploy指令即可將專案部署到私服對應的倉庫中,此時專案中的打包方式多為jar
  • 但需要提前在專案的pom.xml中配置部署私服倉庫位置,如下:

注意: 如上的 repository的 id 依然是要和settings.xml中配置的server中的id 一致,才能通過私服的認證

<project>
        ...
    <dependencies>
        .....
    </dependencies>

    <!-- 在專案的pom.xml中 配置私服的倉庫地址,可以將專案打jar包部署到私服 -->
    <distributionManagement>
        <repository>
            <id>nexus-public</id> <!-- nexus認證id -->
            <url>http://localhost:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>nexus-public</id> <!-- nexus認證id -->
            <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>
</project>

五、IDEA中的Maven操作

5.1 建立Maven專案

建立Maven專案
image-20200616215847109
image-20200616215847109
指定專案名稱和專案位置
image-20200616220455702
image-20200616220455702
5.1.1 節點配置解析
節點 詳細描述
groupId 這是專案組的編號,這在組織或專案中通常是獨一無二的。 例如,一家銀行集團 com.company.bank擁有所有銀行相關專案。
artifactId 這是專案的 ID。這通常是專案的名稱。 例如,consumer-banking。 除了 groupId 之外,artifactId 還定義了 artifact 在儲存庫中的位置。
version 這是專案的版本。與 groupId 一起使用,artifact 在儲存庫中用於將版本彼此分離。 例如:com.company.bank:consumer-banking:1.0com.company.bank:consumer-banking:1.1
5.1.2 語義化版本號
  • 規則:正式穩定版本從v0.1.0開始,配套軟體公共API
  • 注意:正式版釋出後不可修改,只能在下一個版本中釋出新內容
版本型別 詳細描述
主要版本 當你做了不相容的API 修改(正式版釋出、架構升級)
次要版本 當你做了向下相容的功能性新增(功能增減)
修訂版本 當你做了向下相容的問題修正(BUG修復、查缺補漏)
5.1.3 擴充套件(SNAPSHOT)

在使用maven過程中,我們在開發階段經常性的會有很多公共庫處於不穩定狀態,隨時需要修改併發布,可能一天就要釋出一次,遇到bug時,甚至一天要釋出N次。我們知道,maven的依賴管理是基於版本管理的,對於釋出狀態的artifact,如果版本號相同,即使我們內部的映象伺服器上的元件比本地新,maven也不會主動下載的。如果我們在開發階段都是基於正式釋出版本來做依賴管理,那麼遇到這個問題,就需要升級元件的版本號,可這樣就明顯不符合要求和實際情況了。但是,如果是基於快照版本,那麼問題就自熱而然的解決了,而maven已經為我們準備好了這一切。

maven中的倉庫分為兩種,snapshot快照倉庫和release釋出倉庫。snapshot快照倉庫用於儲存開發過程中的不穩定版本,release正式倉庫則是用來儲存穩定的發行版本。定義一個元件/模組為快照版本,只需要在pom檔案中在該模組的版本號後加上-SNAPSHOT即可(注意這裡必須是大寫),如下:

<groupId>cc.mzone</groupId>
<artifactId>m1</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>

maven會根據模組的版本號(pom檔案中的version)中是否帶有-SNAPSHOT來判斷是快照版本還是正式版本。如果是快照版本,那麼在mvn deploy時會自動釋出到快照版本庫中,會覆蓋老的快照版本,而在使用快照版本的模組,在不更改版本號的情況下,直接編譯打包時,maven會自動從映象伺服器上下載最新的快照版本。如果是正式釋出版本,那麼在mvn deploy時會自動釋出到正式版本庫中,而使用正式版本的模組,在不更改版本號的情況下,編譯打包時如果本地已經存在該版本的模組則不會主動去映象伺服器上下載

在maven的約定中,依賴的版本分為兩類——SNAPSHOT和RELEASE。SNAPSHOT依賴泛指以-SNAPSHOT為結尾的版本號,例如1.0.1-SNAPSHOT。除此之外,所有非-SNAPSHOT結尾的版本號則都被認定為RELEASE版本,即正式版,雖然會有beta、rc之類說法,但是這些只是軟體工程角度的測試版,對於maven而言,這些都是RELEASE版本。所以一般我們需要上傳到釋出倉庫的時候可以在<version>標籤內直接寫版本即可,不需要再新增任何標籤!

5.2 IDEA關聯Maven

在IDEA中關聯本地安裝的maven,後續就可以通過idea來使用maven管理專案(我使用的aliyun倉庫)

在全域性設定中關聯Maven
image-20200616222756521
image-20200616222756521
Maven專案展示 (缺少test包下resources資料夾)
image-20200616224937892
image-20200616224937892

5.3 IDEA建立測試包下resources資料夾

我們在使用IDEA建立Maven專案時,IDEA是沒有幫我們建立test包下的resources資料夾。但是Maven規範中是包含這個資料夾的,所以我們需要手動建立並宣告該資料夾

建立存放測試配置的資料夾
image-20200616225355373
image-20200616225355373
指定資料夾名稱 (下拉框選擇resources資料夾建立即可)
image-20200616225859663
image-20200616225859663
檔案目錄結構展示 (完整Maven規範目錄結構)
image-20200616230042781
image-20200616230042781

5.4 Maven專案目錄結構解析

注意: 專案中的建立包、建立類、執行,都與普通專案無異

目錄名稱 描述
src/main/java 用於建立包,存放編寫的原始碼(.java檔案)
src/main/resources 存放專案中所需配置檔案,比如:c3p0.properties
src/test/java 用於建立包,存放編寫的測試程式碼(.java檔案)
src/test/resources 存放專案中測試程式碼所需配置檔案
根目錄/pom.xml 專案物件模型(project object model),maven專案核心檔案,其中定義專案構建方式,宣告依賴等

5.5 Maven專案型別

根據專案型別,在pom.xml檔案中新增相應配置。

  • 專案型別分為Java專案和JavaWeb專案

  • 如果專案為Java專案需要在<project>標籤內新增jar

  • 如果專案為JavaWeb專案需要在<project>標籤內新增war

注意: Maven可以根據專案型別來確定打包方式,比如Java專案打包成jar包JavaWeb專案打包成war包

<?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.mylifes1110</groupId>
    <artifactId>firstmaven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--
        設定專案型別,打包方式:
        如果為Java專案則使用jar
        如果為JavaWeb專案使用war
    -->
    <packaging>jar</packaging>
<!--    <packaging>war</packaging>-->
</project>

5.6 IDEA中匯入依賴

5.6.1 匯入依賴須知

建好專案後,需要匯入需要的jar包,要通過座標來在倉庫中查詢匯入

  • 每個構件都有自己的座標,其座標分為groupId、artifactId、version 三種,翻譯後為專案標識、專案名稱、版本號
  • 在maven專案中只需要配置座標,maven便會自動載入對應依賴。刪除座標則會移除依賴
節點 描述
project 工程的根標籤。
modelVersion 模型版本需要設定為 4.0。
groupId 這是工程組的標識。它在一個組織或者專案中通常是唯一的。例如,一個銀行組織 com.companyname.project-group 擁有所有的和銀行相關的專案。
artifactId 這是工程的標識。它通常是工程的名稱。例如,消費者銀行。groupId 和 artifactId 一起定義了 artifact 在倉庫中的位置。
version 這是工程的版本號。在 artifact 的倉庫中,它用來區分不同的版本。例如:com.company.bank:consumer-banking:1.0 com.company.bank:consumer-banking:1.1
5.6.2 查詢依賴

依賴查詢服務需要在如下網址中查詢依賴,獲取依賴座標後,在maven專案中的pom.xml檔案中匯入

查詢jar檔案
image-20200616111418839
image-20200616111418839
jar檔案的選擇
image-20200616112444879
image-20200616112444879
Copy依賴座標
image-20200617003002005
image-20200617003002005
5.6.3 匯入依賴

在專案的pom.xml檔案中新增依賴

  • 首先新增<dependencies>標籤
  • 最後新增複製好的依賴座標

注意: 匯入依賴可以匯入多個所需jar檔案的依賴,依次在<dependencies>標籤內新增依賴座標即可

匯入依賴
image-20200617003853705
image-20200617003853705
5.6.4 同步依賴

匯入依賴後,你會發現pom.xml檔案中的依賴座標是紅色報錯的,而在IDEA的右下角有那麼一個框。這時候需要點選框內提示資訊在maven倉庫中同步下載依賴到專案中

同步下載依賴到專案中
image-20200617004515463
image-20200617004515463
5.6.5 檢視依賴

匯入並同步下載好的依賴,可以通過專案和IDEA中Maven控制皮膚檢視

檢視依賴
image-20200617005635304
image-20200617005635304

5.7 基於Maven建立Web專案

5.7.1 修改web專案打包方式

pom.xml檔案中設定 <packaging>war/packaging>修改打包方式為web專案

5.7.2 匯入web依賴

基於Maven專案,我們匯入了maven所需依賴,如果建立web專案的話,還需要匯入JSPServletJSTL依賴,使Maven專案具有web編譯環境。(在pom.xml檔案中新增以下依賴)

        <dependency>
            <!-- jstl 支援 -->
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <!-- servlet編譯環境 -->
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- jsp編譯環境 -->
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
image-20200617123210482
image-20200617123210482
5.7.3 建立web專案目錄結構

web專案在IDEA中有web規範目錄資料夾的,比如webapp、WEB-INF、web.xml、index.jsp。而由於Maven專案中沒有該規範目錄,這就需要我們自己建立目錄結構了!

建立web專案目錄結構有以下注意點:

  • webapp資料夾必須是基於main目錄下建立的,與java資料夾同級
  • webapp資料夾IDEA自動識別此資料夾,給與了特殊藍色圓點標識
  • 在WEB-INF目錄下建立的的web.xml是一個空的xml檔案,我們需要在該檔案中鍵入如下web.xml空白模板資訊,只需要將下面的模板複製到專案中的web.xml檔案中即可!
  • 建立的資料夾以及檔名稱千萬不要寫錯!

注意: 在建立專案的時候,其實我們是可以指定使用IDEA來建立來建立web專案的目錄結構的,建立專案時需要勾選Create from archetype。只是IDEA為我們構建的專案架構是有版本差異的,而且還附加了很多對我們無用的註解等等,所以我們一般都手動建立,IDEA自動構建作為了解就好!

xml空白模板

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
</web-app>
IDEA自動構建專案結構
image-20200617164915737
image-20200617164915737
手動構建web專案結構
基於main目錄下建立webapp資料夾
image-20200617124249878
image-20200617124249878
image-20200617124319926
image-20200617124319926
基於webapp目錄建立WEB-INF資料夾
image-20200617124624648
image-20200617124624648
基於WEB-INF目錄建立web.xml檔案
image-20200617125038803
image-20200617125038803
image-20200617125055216
image-20200617125055216
xml檔案內容展示
image-20200617125729115
image-20200617125729115
基於webapp目錄建立index.jsp檔案
image-20200617125613861
image-20200617125613861
目錄展示 (完整的web專案目錄結構)
image-20200617125808227
image-20200617125808227
5.7.4 tomact的引入

關於Tomact服務的引入,需要我們手動新增tomact服務

新增tomact服務後,如果對tomact伺服器在IDEA中的開發流程不熟悉的小夥伴,不要灰心。請參考tomact伺服器基礎和開發步驟即可,此文章中詳細講到了關於tomact的各種知識點!

新增tomact服務
image-20200617131801103
image-20200617131801103

5.8 pom檔案的其他標籤操作

5.8.1 build標籤修改預設打包名

預設的打包名稱:artifactid+verson.打包方式

我們可以通過build中finalName修改,如下操作:

<build>
  <finalName>maven_name</finalName>
</build>  
5.8.2 引入外掛

dependencies引入開發需要的jar包,有時候我們還需要引入一些常用的外掛,比如:jdk、tomact、分頁外掛等等

外掛配置位置也是在<build>標籤中,如下:

<build>
<plugins>
    <!-- java編譯外掛,配jdk的編譯版本 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin>
    <!-- tomcat外掛 -->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <configuration>
        <port>8080</port>
        <path>/</path>
        <uriEncoding>UTF-8</uriEncoding>
        <server>tomcat7</server>
      </configuration>
    </plugin>
  </plugins>
</build>
5.8.3 控制打包資源

如果在java資料夾中新增java類,會自動打包編譯到classes資料夾下。但是xml檔案預設不會被打包,需要我們手動指定打包。可以使用<resources>標籤來指定要打包資源的資料夾要把哪些靜態資源打包到classes根目錄下

<!--打包指定靜態資源-->
<build>
<resources>
    <resource>
      <!-- 指定要打包資源的資料夾 要把哪些靜態資源打包到 classes根目錄下-->
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/
*.properties</include>
      </includes>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <excludes>
        <exclude>spring/*</exclude>
      </excludes>
      <includes>
        <include>*.xml</include>
        <!--<include>*/
*.properties</include>-->
      </includes>
    </resource>
  </resources>
</build>

六、依賴的生命週期

6.1 什麼是依賴的生命週期

jar檔案的生效時間段可以成為依賴的生命週期

6.2 依賴的生命週期分類與詳解

前三個是常用的依賴生命週期設定,而後兩個製作瞭解即可,幾乎用不到!

標識 週期
compile 預設值(預設依賴生命週期),適用於所有階段(測試執行,編譯,執行,打包)
provided 類似compile,期望JDK、容器或使用者會提供這個依賴。如servlet-api.jar;適用於(測試執行,編譯)階段
test 只在測試時使用,適用於(編譯,測試執行)階段,如 junit.jar
runtime 依賴在編譯器不使用,只在執行時使用,如 mysql的驅動jar,適用於(執行,測試執行)階段
system Maven不會在倉庫中查詢對應依賴,在本地磁碟目錄中查詢;適用於(編譯,測試執行,執行)階段

6.3 依賴生命週期的使用

關於依賴生命週期的使用,需要在期望指定生命週期的依賴內新增<scope>標籤,在此標籤內新增所需依賴標識。

complie

jstl依賴預設沒有compile標識的生命週期。因為在依賴中不指定生命週期就是預設指定適用於所有階段的生命週期,其預設標識為compile。

image-20200617135847510
image-20200617135847510

provided

servlet和jsp依賴預設指定provided標識的生命週期。因為我們在servlet或jsp程式碼時是需要這兩個依賴的,但是我們將專案部署到tomact中,本地tomact目錄的lib資料夾下也會有一些jar檔案,所以這造成了一種依賴衝突。為了避免這種依賴衝突我們需要指定依賴的生命週期為編譯和測試執行階段。這樣我們在書寫程式碼時,編譯期也有有依賴可以使用,不會飄紅,而在過了編譯期後專案部署到了tomact中,該依賴聲生命就會被結束掉了,不會影響tomact伺服器內建依賴的使用!

image-20200617135818392
image-20200617135818392

test

在maven專案中,專案結構是區分main主檔案和test測試檔案的。如果我們在使用Junit單元測試時,指定依賴的生命週期為test,那該依賴只適用於test測試檔案內,在其他檔案的階段預設沒有單元測試的依賴。

簡單來說,在test資料夾內建立的測試類,使用@Test註解不會有任何問題。如果換做在main資料夾和其他資料夾中建立測試類,使用@Test註解就會因沒有依賴注入而報錯。

image-20200617140515452
image-20200617140515452

runtime

我們在新增mysql驅動的依賴時,你會發現它並沒有指定生命週期為runtime。這是因為我們在書寫jdbc工具類的操作時,如果在編譯期沒有mysql驅動的依賴,它並不會飄紅報錯。如果沒有依賴只有在我們執行的時候才會發生報錯,並告知mysql驅動依賴未找到。所以,這就顯得runtime這個依賴生命週期十分的雞肋。因此,可以不指定該生命週期。

image-20200617141145812
image-20200617141145812

system

當依賴的生命週期設定為system時,表示該依賴項是我們自己提供的,不需要Maven到倉庫裡面去找。
指定scope為system需要與另一個屬性元素systemPath一起使用,它表示該依賴項在當前系統的位置,使用的是絕對路徑。由於此類依賴不是通過 Maven 倉庫解析的,而且往往與本機系統繫結,可能造成構建的不可移植,因此應該慎用。systemPath 元素可以引用環境變數。

image-20200617142301138
image-20200617142301138

七、maven的構建命令

7.1 專案的構建過程

7.2 常用構建命令

一般命令的鍵入在IDEA中的框中鍵入命令就可以!

image-20200617170717904
image-20200617170717904
命令 描述
mvn compile(常用) 編譯專案,生成target檔案
mvn package(常用) 打包專案,生成war或jar檔案
mvn clean(常用) 清理編譯或打包後的專案結構
mvn install(常用) 打包後上傳到Maven本地倉庫
mvn source:jar 打包專案,生成jar包
mvn deploy 只打包,不測試
mvn site 生成站點
mvn test 執行測試原始碼

7.3 maven專案的生命週期

maven專案的生命週期分為了三個階段,而這三個階段相互獨立、互不影響

  1. 清理生命週期(Clean Lifecycle): 該生命週期負責清理專案中多餘資訊,保持資源和程式碼的整潔性。一般用來清空目錄下的檔案
  2. 預設構建生命週期(Default Lifeclyle): 該生命週期表示專案的構建過程,其中定義了一個專案構建要經歷的不同階段
  3. 站點管理生命週期(Site Lifecycle): site生命週期的目的是建立和釋出專案站點,Maven能夠基於POM所包含的資訊,自動生成一個友好的站點

clean

該生命週期主要是對專案編譯生成的檔案進行清理,清理的話主要是清理編譯後專案中的target資料夾,清理後還可以通過編譯指令重新生成。

  • 命令: mvn clean

default

該生命週期的主要目的是專案的編譯 -> 測試 -> 打包 -> 釋出

  • 命令: mvn deploy
  • 其中default生命週期分為23個階段,如下列舉比較重要的幾個階段
  • validate:驗證工程是否正確,所有需要的資源是否可用。
  • compile:編譯專案的原始碼。
  • test:使用合適的單元測試框架來測試已編譯的原始碼。這些測試不需要已打包和佈署。
  • Package:把已編譯的程式碼打包成可釋出的格式,比如jar。
  • integration-test:如有需要,將包處理和釋出到一個能夠進行整合測試的環境。
  • verify:執行所有檢查,驗證包是否有效且達到質量標準。
  • install:把包安裝到maven本地倉庫,可以被其他工程作為依賴來使用。
  • Deploy:在整合或者釋出環境下執行,將最終版本的包拷貝到遠端的repository,使得其他的開發者或者工程可以共享。

site

該生命週期的主要是建立和釋出專案站點,Maven能夠基於POM所包含的資訊,自動生成一個友好的站點

  • 命令: mvn site

注意: 低版本的site外掛可能引發失敗現象!升級高版本site外掛即可!

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-site-plugin</artifactId>
  <version>3.7.1</version>
</plugin>

7.4 maven命令與外掛的關係

maven命令是操作maven專案的重要方式,但是我們要知道maven命令只是支配maven外掛工作的一個方式,其工作核心主要還是maven外掛。maven內嵌了專案操作的外掛,我們只需要通過執行命令來呼叫外掛來完成專案的編譯、測試、釋出等工作

注意: 執行一次命令可能會觸發多個外掛工作

八、傳遞依賴和衝突解決

8.1 什麼是傳遞依賴

假如有Maven專案A,專案B依賴A,專案C依賴B。那麼我們可以說 C依賴A。也就是說,依賴的關係為:C - > B - > A, 那麼我們執行專案C時,會自動把B、A都下載匯入到C專案的jar包資料夾中,這就是依賴的傳遞性。

8.2 什麼是依賴衝突

依賴衝突我在上文中也提到過,依賴衝突是當直接引用或者間接引用出現了相同的jar包擁有不同版本的時候。

舉個例子:A依賴於B,B依賴於C,此時C的版本為V1.0;如果此時引入的C依賴還有一個V2.0,那麼我們的A傳遞依賴於C,此時C的版本為V2.0。這時候就是一個衝突,直接或間接的都引用了C,而C版本有兩個!

8.3 手動解決依賴衝突

如果我不想在C依賴中出現B,那麼就可以主動的使用依賴排除技術,排除B依賴的引用,如下操作需要新增排除依賴的配置資訊(<exclusions>標籤和其中資訊,其中兩個id標籤是需要排除依賴的id):

     <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.12.RELEASE</version>

            <!--手動排除依賴-->
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>

        </dependency>
     </dependencies>

8.4 自動解決依賴衝突

8.4.1 自動解決依賴衝突的途徑

自動解決依賴通途問題的兩個途徑分為:短路優先原則先宣告優先原則

8.4.2 短路優先原則

首先,先看如下依賴關係

  1. A - > B - > C - > D - > E(V1.0)
  2. A - > F - > E(V2.0)

解釋: 1中,A依賴於B,B依賴於C,C依賴於D,D依賴於E,此時E的版本為V1.0版本(2中解釋基本相似)

所謂短路優先,就是路徑段的依賴有限被載入使用,這裡我們可以看到2中的路徑是最短的路徑,所以maven在載入依賴的時候,是使用2中的這一條依賴和版本

8.4.3 先宣告優先原則

針對依賴路徑長度相同的情況,則使用先宣告優先原則,看如下依賴關係

  1. A - > B - > C(V1.0)
  2. A - > D - > C(V2.0)

此時路徑優先原則不能解決問題時,maven需要判斷在A專案的<depencies>標籤內,B和D的哪個依賴宣告在前面,如果B依賴宣告早於D依賴,那麼就使用1中的這一條依賴和版本

微信公眾號
微信公眾號

相關文章