Maven 基礎(一) | 使用 Maven 的正確姿式

1、什麼是 Maven?

Maven 是一個項目管理工具,它的本質是一個項目對象模型(POM),體如今配置中就是咱們常見的 pom.xml 文件,而這個 pom 文件就是 Maven 的核心,它管理了整個項目的生命週期。它主要作兩件事:html

  • 項目構建:對項目進行編譯、打包、測試、部署以及上傳到私服倉庫等前端

  • 依賴管理:Maven 誕生時就提出了一個倉庫的概念,項目中用到的第三方 jar 包,咱們在 pom.xml 中配置好依賴便可,Maven 會自動到它的官方中央倉庫下載這個 jar 包到咱們的本地倉庫。java

  • 中央倉庫地址:mvnrepository.com/python

2、爲何要使用 Maven?

  • 方便依賴管理:Java 發展至今,生態很是完善。咱們在項目中用到什麼功能,網上一搜確定有對應的 jar 包,各類功能就致使了各類 jar 包的引入,這些 jar 包之間可能會有依賴,可能會有版本衝突。而 Maven 的誕生解決了這些問題。mysql

  • 構建多模塊項目:如今不少項目都是分了多個模塊,便於開發、也便於擴展。多模塊就意味着模塊之間會有各類依賴,咱們運行某個模塊,可能這個模塊依賴了別的模塊。而 Maven 的一鍵構建項目幫咱們解決了這個問題。linux

  • 方便移植:之前沒 maven 的時代,團隊協做要上傳、下載一大堆 jar 包導入項目,耗時、費力。而有了 maven ,咱們只須要同步一下 pom 文件便可同步 jar 包。這是 maven 解決的第三個問題。c++

3、怎麼使用 Maven?

3.1 Maven 的安裝

這個就不講了,網上不少資料。好比:www.cnblogs.com/KyleXu/p/99…算法

3.2 Maven 的配置

Maven 的配置比較簡單,主要是修改 conf 文件夾下的 setting 文件。配置如下三個倉庫:spring

本地倉庫sql

項目依賴的 jar 包是須要下載到本地才能用的。本地倉庫就是從 maven 私服或者遠程倉庫下載的 jar 的存儲地址,默認是 當前用戶名\.m2\repository ,我建議改個好記的地方,後面方便檢查包有沒下載到本地。打開 setting.xml 搜索 localRepository 修改爲自定義的地址。

<localRepository>D:\Repository</localRepository>
複製代碼

配置的位置,以下圖:

本地倉庫

私服倉庫

這個倉庫的話,通常就是公司內部使用的啦。用來存儲公司內部本身的 jar 包。打開 setting.xml 文件搜索 mirrors ,配置公司的鏡像地址便可。

<mirror>
	<id>nexus-repos</id>
	<mirrorOf>*</mirrorOf>
	<name>Team Nexus Repository</name>
	<url>http://127.0.0.1:8081/nexus/content/groups/public</url>
</mirror>
複製代碼

遠程倉庫

遠程倉庫就是一個 maven 官方維護的,包含大量 jar 包的倉庫。這個庫默認是 maven 官方的,可是下載很是慢。因此業界典範阿里巴巴也推出了一個國內的鏡像,咱們通常把遠程倉庫配成阿里的鏡像地址,就能夠快速地下載 jar包啦。和私服倉庫同樣,遠程倉庫也是配置在 <mirrors> 標籤內。

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

配置的位置,以下圖:

遠程倉庫

有人可能問了,配置那麼多個倉庫。究竟 jar 從哪一個下載的呀?都把我搞糊塗了,別急,我花了個流程圖,它的查找順序是這樣的:本地不須要網絡,優先從本地找;找不到,再去速度較高的內網私服找;而後纔是速度稍低的外網遠程倉庫找。

maven 查找文件流程

3.3 Maven 的命令

經常使用命令

命令 含義 備註
mvn clean 清除 打包前,清空上一次的包
mvn compile 編譯 將 java 代碼編譯成 class 文件
mvn test 測試 運行單元測試
mvn install 安裝到本地 安裝到本地倉庫,通常是 jar 包
mvn package 打包 通常會在 target 目錄下生成包,jar 或 war
mvn deploy 上傳 上傳到私服,需在 setting.xml 文件配置私服倉庫以及帳號密碼

以上就是 maven 經常使用的命令,要注意的是:不多狀況下咱們只運行其中一個命令,都是組合運行的。好比打包到本地,打包前得清空原有的包吧?那組合起來就是 mvn clean + mvn install

固然,在 IDEA 中開發 maven 項目,咱們並不須要手打。只需點擊對應命令便可(也能夠按住 ctrl 選中多個命令一塊兒運行)

maven 操做

總而言之,根據本身的需求來選擇打包命令。還有其餘的命令請見:

建立 maven 項目

如今通常都是配合 idea 新建 maven 項目了,這個命令用得不多,但咱們仍是得知道一下:生成 maven 項目的原理是,依賴一個插件 maven-archetype-plugin,而後這個插件自帶一些 archetype 模版,也能夠說成項目的骨架。其中:-DgroupId-DartifactId填寫本身想好的項目座標,通常 -DgroupId是公司名的翻轉,好比 com.google-DartifactId 就是項目的名稱了。最重要的是-DarchetypeArtifactId,他指定了建立的骨架。

mvn archetype:generate -DgroupId=com.nasus -DartifactId=maven-test -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
複製代碼

建立 maven 項目成功

點進去,只有 src文件夾和 pom.xml文件:src 是最重要的目錄,代碼和測試用例以及資源都是放在這裏的,對於 maven 項目而言,pom.xml 也是必不可少的。

項目結構

idea 打開的項目結構是這樣的:

idea 打開

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">

    <!--聲明項目描述符遵循哪個 POM 模型版本,上面的 xsd 規範定義了這個版本,默認就行,不須要修改,不可刪除-->
    <modelVersion>4.0.0</modelVersion>

    <!--團體惟一標識符-->
    <groupId>com.nasus</groupId>

    <!--項目惟一標識符定位這個包-->
    <artifactId>maven-test</artifactId>

    <!--打包類型-->
    <packaging>jar</packaging>

    <!--打包版本-->
    <version>1.0-SNAPSHOT</version>

    <!--包名-->
    <name>maven-test</name>

    <!--不用管,刪掉也行-->
    <url>http://maven.apache.org</url>

    <!--項目須要依賴的 jar 包-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
複製代碼

因爲篇幅緣由,這裏就不詳細講具體的 pom.xml 標籤了,詳細介紹請看:

項目打包到本地倉庫

因爲項目是 java 項目,在打包前,咱們要在 pom.xml 中配置項目的 JDK 版本以及 maven 插件版本,在 <dependencies> 標籤前加入項目屬性配置,完整配置以下:

<!--項目屬性,在 <dependencies> 前加-->
    <properties>
        <!-- JDK編譯版本 -->
        <java.version>1.8</java.version>
        <!-- 項目編碼 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- JDK編譯版本 -->
        <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>
    <!--項目須要依賴的 jar 包-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
複製代碼

選擇命令,這裏我選了 clean、compile、package

選擇命令

點擊綠色執行按鈕,在 target 目錄下生成 maven-test-1.0.SNAPSHOT.jar:

打包結果

跳過單元測試

在開發中,咱們常常須要本地測試,而這時咱們是不須要跑單元測試的。因此,咱們能夠跳過單元測試:選中 test,點擊紅框按鈕便可。

跳過單元測試

手動打 jar 包到本地倉庫

手動打 jar 包的應用場景是:開發公司舊項目,當找不到依賴的 jar 源碼,依賴的 jar 又沒有上傳到倉庫,只有在同事電腦的本地倉庫有一個 jar 包時,咱們能夠直接運行這條命令把 jar 包打到咱們電腦本地倉庫,愉快的使用起來。

mvn install:install-file -Dfile=jar包的路徑 -DgroupId=gruopId中的內容 -DartifactId=actifactId的內容 -Dversion=version的內容 -Dpackaging=jar
複製代碼

4、maven 依賴管理

maven 經過 pom.xml 來進行依賴管理,咱們用它來描述項目的依賴屬性。能夠把它看做是 maven 項目的地圖,它描述了 jar 包的座標、版本以及依賴關係等。若是不肯定你想要引入 jar 的座標怎麼寫,能夠上 maven 中央倉庫查詢:

4.1 maven 座標

maven 的第三方依賴都在 <dependencies>標籤內定義,該標籤下的 <dependency> 包裹的內容就是一個 jar 的座標,以下 pom 就引入了 junitcglib 兩個 jar 。下面就說一下每一個座標的標籤都表明什麼。

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
    </dependency>
</dependencies>
複製代碼
  • dependencies

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

  • dependency

一個 dependency 標籤表示一個座標,也就是一個 jar,在 pom 中引入一個 jar 能夠這樣寫:

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

公司、團體、我的開發者的惟一標識符,maven 約束它以建立這個項目的組織名稱的逆向域名開頭,好比開發者的域名是 nasus.com 那他的惟一標識符就是 com.nasus

<!--團體惟一標識符-->
<groupId>com.nasus</groupId>
複製代碼
  • artifactId

項目惟一標識符,一個組織可能有多個項目,爲了方便 maven 引入,maven 約定以項目名稱命名該標識符,好比我開發的 maven-test 項目。

<!--項目惟一標識符-->
<artifactId>maven-test</artifactId>
複製代碼
  • version

項目的版本。一個項目,可能會有多個版本。若是是正在開發的項目,咱們能夠給版本號加上一個 SNAPSHOT,表示這是一個快照版本。

什麼是快照?

對於版本,若是 maven 之前下載過指定的版本文件,好比說 maven-test:1.0maven 將不會再從倉庫下載新的可用的 1.0 文件。若要下載更新的代碼,maven-test 的版本須要升到 1.1

快照是一種特殊的版本,指定了某個當前的開發進度的副本。不一樣於常規的版本,maven 每次構建都會在遠程倉庫中檢查新的快照。咱們本身的模塊依賴了同事開發的模塊,正常來講,同事會每次發佈更新代碼的快照到倉庫中。

新建項目的默認版本號就是快照版,好比上面用 maven 命令新建的 maven-test 項目:

SNAPSHOT

4.2 依賴範圍

  • scope

maven 項目不一樣的階段引入到 classpath 中的依賴是不一樣的,例如,編譯時,maven 會將與編譯相關的依賴引入 classpath 中,測試時,maven 會將測試相關的的依賴引入到 classpath 中,運行時,maven 會將與運行相關的依賴引入 classpath 中,而依賴範圍就是用來控制依賴於這三種 classpath 的關係。 以下圖所示:

依賴傳遞,圖:菜鳥教程

scope 表示依賴的範圍,它有 compile(編譯階段)、test(測試階段)、provided(供應階段)、runtime(運行階段)、system(系統階段)、import(導入階段) 六個可選值。其中 compile 是默認的。systemimport 用得少,不詳細講。

不一樣依賴的適用範圍不同,舉幾個最典型的栗子:

範圍 編譯有效 測試有效 運行時有效 打包有效 示例
compile spring-core
test junit
provided javax.servlet-api
runtime JDBC驅動
  • compile: 編譯依賴範圍。若是沒有指定,就會默認使用該依賴範圍。使用此依賴範圍的 Maven 依賴,對於編譯、供應、測試、運行四種 classpath 都有效。好比 spring-core

  • provided: 已提供依賴範圍。使用此依賴範圍的 Maven 依賴,對於 編譯和測試 classpath 有效,但在運行時無效。典型的例子是 servlet-api 編譯和測試項目的時候須要該依賴,但在運行項目的時候,因爲容器已經提供,就不須要 maven 重複地引入一遍:

<dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>3.1.0</version>
     <scope>provided</scope>
</dependency>
複製代碼
  • test: 單元測試依賴範圍,只在測試的時候生效,因此能夠設置它的 scope 爲 test,這樣,當項目打包發佈時,單元測試的依賴就不會跟着發佈。好比:
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>
複製代碼
  • runtime: 運行時依賴範圍。對於測試和運行 classpath 有效,但在編譯主代碼時無效。典型的例子是 JDBC 驅動實現,項目主代碼的編譯只須要 JDK 提供的 JDBC 接口,只有在執行測試或者運行項目的時候才須要實現上述接口的具體 JDBC 驅動。因此,咱們使用 JDBD 驅動時,能夠定義成如下樣例:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.12</version>
    <scope>runtime</csope>
</dependency>
複製代碼

4.3 排除依賴

以下 xml,原來的定義中已引入 commons-net 依賴,而 hermes-ftp 中又依賴了 commons-net,爲避免版本衝突,咱們能夠排除 hermes-ftp 中的 commons-net 依賴。

<dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>3.6</version>
</dependency>
<dependency>
    <groupId>com.nasus.greece.jupiter</groupId>
    <artifactId>hermes-ftp</artifactId>
    <version>1.1.0-SNAPSHOT</version>
    <!--排除 commons-net 依賴-->
    <exclusions>
        <exclusion>
            <artifactId>commons-net</artifactId>
            <groupId>commons-net</groupId>
        </exclusion>
   </exclusions>
</dependency>
複製代碼

4.4 依賴傳遞

假設有以下項目關係:WebMavenDemo 項目依賴 JavaMavenService1JavaMavenService1 項目依賴 JavaMavenService2

項目關係

pom.xml 文件配置好依賴關係後,必須首先 mvn install 後,依賴的 jar 包才能使用。好比:

  • WebMavenDemopom.xml 文件想能編譯經過,JavaMavenService1 必須 mvn install
  • JavaMavenServicepom.xml 文件想能編譯經過,JavaMavenService2 必須 mvn install

傳遞性:

傳遞性

假設咱們如今 JavaMavenService2 增長 spring-core ,那就會發現WebMavenDemoJavaMavenService1 也會自動的增長了這個jar包,這就是依賴的傳遞性。

注意:非 compile 範圍的依賴是不能傳遞的。

  • 來源:cnblogs.com/hzg110/p/6936101.html

4.5 統一管理依賴版本

在上面介紹 pom 文件時,咱們講過 properties 標籤,它還有一個做用就是限定依賴的 jar 包版本,它經常使用在父項目中指定版本號,那麼子項目用到該包就避免了版本不一致形成的依賴衝突,它的寫法是這樣的:

統一管理版本

5、build 配置

maven 打 war 包時,可能須要一些額外的配置,請參看如下 xml 文件:

<build>
        <!-- 項目的名字 -->
        <finalName>maven-test</finalName>
        <!-- 描述項目中資源的位置 -->
        <resources>
            <!-- 自定義資源1 -->
            <resource>
                <!-- 資源目錄 -->
                <directory>src/main/java</directory>
                <!-- 包括哪些文件參與打包 -->
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <!-- 排除哪些文件不參與打包 -->
                <excludes>
                    <exclude>**/*.txt</exclude>
                    <exclude>**/*.doc</exclude>
                </excludes>
            </resource>
        </resources>
        <!-- 設置構建時候的插件 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <!-- 源代碼編譯版本 -->
                    <source>1.8</source>
                    <!-- 目標平臺編譯版本 -->
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- 資源插件(資源的插件) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>compile</phase>
                    </execution>
                </executions>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- war插件(將項目打成war包) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <!-- war包名字 -->
                    <warName>maven-test</warName>
                </configuration>
            </plugin>
        </plugins>
    </build>
複製代碼

6、使用 idea 搭建 maven 聚合工程

這個網上不少資料,不講了。留個連接。

最後

若是看到這裏,喜歡這篇文章的話,請轉發、點贊。微信搜索「一個優秀的廢人」,歡迎關注。

回覆「1024」送你一套完整的 java、python、c++、go、前端、linux、算法、大數據、人工智能、小程序以及英語教程。

回覆「電子書」送你 50+ 本 java 電子書。

編程語言
相關文章
相關標籤/搜索