JAVA學習之maven的使用


場景 : 最近使用springboot寫一些小demo,發現到處都要使用maven,更離不開其中的pom.xml文件,所以這里對maven的常規使用作出一個整理。

轉載自 : 本文很多內容都是仿照 http://www.cnblogs.com/qbzf-Blog/p/6539161.html 來的。而且他還提供了一個慕課網的學習視頻:http://www.imooc.com/learn/443


 

文章結構 : 

1. 安裝配置maven環境

2. maven目錄結構

3. HelloMaven

4. 常用構建命令

5. 使用archetype插件自動建立目錄

6. 坐標&倉庫

7. 生命周期&插件的使用

8. pom.xml常用標簽介紹

9. maven依賴(范圍、傳遞、沖突)

10. 聚合&繼承

 

 


 

正文 : 

 1. 安裝配置maven環境

首先,在官網中下載maven組件。進入官網后,在左邊菜單找到Download選項,點擊進入Download頁面。   

  

 

  

 

當然,我們首先要保證JDK安裝好。接下來,要在本地配置好maven的系統環境變量,

   

新建一個maven_home的變量,然后在系統變量的path后面追加這個maven_home;

   

接着,我們測試下maven安裝成功沒有(注意,一般我們都先安裝好JDK,因為maven的命令應該是要借助jdk的):

  

如圖所示,顯示了maven的版本信息跟jdk的版本信息,當然,我們也可以使用echo 查看下 系統環境變量 :

  

 到這里,我們對maven的環境配置就完成了。其實這是第一種,我們下載jar包的形式,不過本人是使用第二種,直接安裝eclipse(包含maven)的版本即可,

  

比如我安裝的版本即是自帶的maven;接下來只需要配置好本地的系統變量即可。

 誒,如果我們想要改變maven的版本呢,我們可以在eclipse當中的preferences當中改變:

  

 

2.  maven項目的目錄結構 

       先在這里插入一點個人對maven的理解,我們之前每個項目都需要有自己的jar包,但是這么多jar包很多有相同的,而這些jar包又是基於項目存放的,如果我們跨越項目這一層,統一管理jar包呢, 這樣不就可以節約很多空間和時間。所以,我們使用maven工具來支配之,那么我們maven存放jar包的地方就是我們說的倉庫,

 當我們在第一步設置好maven的環境之后,默認就在c盤的user目錄下的.m2文件夾充當倉庫。  

   a

 

        maven在每台機器上創建一個本機倉庫,把本機上所有maven項目依賴的jar包統一管理起來,而且這些jar包用“坐標”來唯一標識(注:坐標是另一個重要的概念,后面還會講到,這里只要簡單理解成“唯一識別某個jar包文件名、版本號”的標識即可),這樣所有maven項目就不需要再象以前那樣把jar包復制到lib目錄中,整個maven項目看起來十分清爽。 

扯了很多,現在說下maven項目的目錄結構是怎樣的 : 

          

 誒,這些有些怎么標紅呢? 是因為我們使用maven約定由於配置。src/main/java約定用於存放源代碼,src/main/test用於存放單元測試代碼,src/target用於存放編譯、打包后的輸出文件。這是全世界maven項目的通用約定,請記住這些固定的目錄結構。

3. 構建一個HelloMaven項目

      上面介紹完了我們該使用怎樣的約定來開發一個項目,接下來我們創建一個項目。

   

new一個maven項目,寫好坐標(待會介紹)。這里說的坐標就是上面的groupid以及artifact id。創建好之后的結構如下圖所示:

   

       接下來我們嘗試編譯下這個項目,命令行進入項目路徑,使用mvn compile命令(當然,直接在eclipse上run as這個項目使用maven的幾個選項都是可以的)。編譯之后會生成target目錄,里面存放的是class文件 : 

  

我們接下來編譯下 : 

     

      

我們查看下項目目錄 : 

    

 我們這里在maven項目的測試類中寫個syso輸出 : 

 

 OK,我們再在控制台輸入mvn clean ,清理下class文件,再輸入mvn compile 再次編譯一下,接着輸入mvn test執行AppTest.class文件:

  

 

我們可以看到已經輸出成功了。

4. 常用構建命令  

      從第3步驟可以看出,這些命令的使用了,其實很像使用java命令編譯對不對。那么我們來介紹下maven的這些構建命令 : 其形式一般都是在命令行 mvn xxx的這種格式 : 

mvn    {

                     -v 查看maven版本以及其他相關信息

      compile 編譯maven項目,並生成target文件夾

      test 運行test目錄下的測試文件,即測試

      package 將項目打包,默認打包為jar格式,也可以打包成war格式用於服務器運行

                     install 將打包的jar文件安裝到maven本地倉庫

                     clean 刪除target,相當於清除緩存

           }

 這些命令在集成了maven的eclipse當中也有對應選項可以操作 : 

  

 我們可以右鍵一個項目,然后run as 就會出現這些選項,在下面的maven當中 還有update選項;

    那這么多命令,我們怎么知道怎么合理使用呢,其實我們只需要理解到整個項目的構建過程就可以明白這一點了:

項目構建過程包括【清理項目】→【編譯項目】→【測試項目】→【生成測試報告】→【打包項目】→【部署項目】這幾個步驟,這六個步驟就是一個項目的完整構建過程。(mvn clean  -> mvn compile  -> mvn test -> mvn package)

    而上面所說的maven update是針對我們在項目中的pom.xml當中引入了新的jar包之后,需要重新update一下,此處的應用場景就是 :

比如我們A項目在pom.xml引入了一個新包,這個時候我們需要把A項目重新update一下才能使用新jar包當中的東西(不過很多時候我們項目有自動重構);如果這個時候我們B項目引用了A,也想使用這個新jar包,我們也應當update一下,避免發生引用錯誤,還有一個常見的使用場景就是我們import一個新的maven聚合項目的時候,需要clean install :

     

然后我們還要update把jar包下下來,這個時候如果依賴包過多,其下載是相當大的,所以我們可以指定maven倉庫的位置為阿里的(更改setting文件后面作出介紹。)

下面我列舉一下常用的maven 命令(注意我上面在eclipse當中不是maven clean 而是clean,原因嗎我也不知道啦):

  • 創建一個簡單的Java工程:mvn archetype:create -DgroupId=com.mycompany.example -DartifactId=Example
  • 創 建一個java的web工程:mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp
  • 打包:mvn package
  • 編譯:mvn compile
  • 編譯測試程序:mvn test-compile
  • 清空:mvn clean
  • 運行測試:mvn test
  • 生成站點目錄: mvn site
  • 生成站點目錄並發布:mvn site-deploy
  • 安裝當前工程的輸出文件到本地倉庫: mvn install
  • 安 裝指定文件到本地倉庫:mvn install:install-file -DgroupId=<groupId> -DartifactId=<artifactId> -Dversion=1.0.0 -Dpackaging=jar -Dfile=<myfile.jar>
  • 查看實際pom信息: mvn help:effective-pom
  • 分析項目的依賴信息:mvn dependency:analyze 或 mvn dependency:tree
  • 跳過測試運行maven任務:    mvn -Dmaven.test.skip=true XXX
  • 生成eclipse項目文件: mvn eclipse:eclipse (將maven項目轉換成eclipse項目)
  • 查看幫助信息:mvn help:help 或 mvn help:help -Ddetail=true
  • 查看插件的幫助信息:mvn <plug-in>:help,比如:mvn dependency:help 或 mvn ant:help 等等。

      這里我還想多說一點,其實maven的功能不僅僅是這樣,如下我列舉一些maven的常用基本功能 :

      (轉載自 https://www.cnblogs.com/adolfmc/archive/2012/07/31/2616908.html)

  • 構建:比如生成class、jar、war或者ear文件
  • 生成文檔:比如生成javadoc、網站文檔
  • 生成報告:比如junit測試報告
  • 生成依賴類庫:生成文檔,說明項目多其他軟件的依賴
  • 有關SCM:SCM(Software Configuration Management),軟件配置管理,比如版本控制,比如bug管理等等
  • 發布:生成供發布的分發包,比如生成Struts2的分發包,供提交給用戶使用
  • 部署:比如,web應用程序,自動部署到指定的服務器上
  • Maven資源

     

 5.使用archetype插件自動建立目錄

      這個本人不作出介紹了,哈哈,沒用過。

6. 坐標和倉庫

  坐標 :

   maven使用groupId、artifactId、version表示坐標,每個坐標都唯一的指向一個maven項目,簡單介紹一下這幾個標簽

      groupId:項目組織唯一的標識符,一般為反寫的公司網址+項目名
      artifactId:項目的唯一的標識符,一般為項目名+模塊名
      version:版本號 x.x.x+版本類型
        第一個x表示大版本號
        第二個x表示分支版本號
        第三個x表示小版本號(可省略)
        常見版本類型:
          snapshot快照
          alpha內部測試
          beta公測
          release穩定
          GA正式發布

      注:包名應與groupId+artifactId相吻合。

       倉庫 : maven的依賴管理是靠着倉庫來支撐的,倉庫分為中央倉庫和本地倉庫。在編譯項目時,maven會根據配置的依賴,現在本地倉庫中進行搜索,若是沒有則再去倉庫進行搜索,而搜索便是采用坐標進行查找。倉庫默認為本地的c盤users文件夾下面的.m2的repository。如果不想放在C盤的話,可以對maven進行配置:

   

         如圖,可以自己重寫localRepository;

7. 生命周期 & 插件的使用

      多個生命周期之間相互獨立。每個生命周期含有多個階段,階段按順序執行,運行后階段時,前階段會自動執行。比如,直接運行mvn test命令,那么執行該命令時,會自動的附帶mvn compile命令,因為test階段在compile階段之后。

       上面我們就說過,一個完整的項目的構建過程包括 : 

        清理、編譯、測試、打包、集成測試、驗證、部署;

         clean 清理項目,包括以下階段:
      pre-clean 執行清理前
      clean 清理上一次構建生成的所有文件
      post-clean 執行清理后的文件
    default 構建項目(核心:常用),包括以下階段
      compile 編譯
      test 測試
      packeage 打包
      install 安裝
    site 生成項目站點,根據pom中信息生成項目站點,包括以下階段
      pre-site 在生成項目站點前要完成的工作
      site生成項目的站點文檔
      post-site在生成項目站點后要完成的工作
      site-deploy發布生成的站點到服務器上

插件:

    maven中提供了許多功能強大的插件,讓我們更好的管理項目。一個插件通常提供了一組目標,可使用以下語法來執行:

      mvn [plugin-name]:[goal-name]
   例如我們之前使用mvn archetype:generate,插件名為archetype,而目標為generate。我們可以在官網的Plugins標簽下,查找到插件的坐標及插件目標的詳細描述。
   Maven 提供以下兩種類型插件:
類型 描述
構建插件 在生成過程中執行,並在 pom.xml 中的<build/> 元素進行配置
報告插件 在網站生成期間執行,在 pom.xml 中的 <reporting/> 元素進行配置

     

以下是一些常見的插件列表:

插件 描述
clean 編譯后的清理目標,刪除目標目錄
compiler 編譯 Java 源文件
surefile 運行JUnit單元測試,創建測試報告
jar 從當前項目構建 JAR 文件
war 從當前項目構建 WAR 文件
javadoc 產生用於該項目的 Javadoc
antrun 從構建所述的任何階段運行一組 Ant 任務
source 從當前項目構建帶源碼的JAR文件

比如我們拿source來測試:

<build>
<!-- 配置插件集 -->
<plugins>
<plugin>
<!--使用插件的坐標進行引用 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>

<executions>
<execution>
<!-- 綁定在哪個過程時一同執行,這里我們讓它在使用package打包時一同執行 -->
<phase>package</phase>
<!--執行的目標類型,關於目標的詳細介紹可以在maven官網中查到-->
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

我們接下來先編譯一下 :

 

然后,我們在來看使用打包命令之后會不會生成源jar包。

 

 我們可以看到在下載很多東西了 ,接下來看下文件夾生成了源jar包沒 : 

從這里我們可看成,這里有幾個關鍵點,在pom.xml當中使用plugin來申明要使用的插件,然后還可以綁定到某個過程中執行,我們這里就綁定到了package當中執行。

8. 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/xsd/maven-4.0.0.xsd">
<!-- 當前pom的版本-->
<modelVersion>4.0.0</modelVersion>

<!--坐標-->
<groupId>cn.edu</groupId>
<artifactId>maven04</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 默認是jar,其他war zip pom等 -->
<packaging>jar</packaging>

<!--項目描述名 -->
<name>maven04</name>
<!-- 項目地址 -->
<url>http://maven.apache.org</url>

<!-- 配置參數 -->
<properties>
<!-- 這里配置項目編譯編碼為UTF-8-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!-- 開發人員信息 -->
<developers></developers>
<!-- 項目描述 -->
<description></description>
<!-- 許可信息 -->
<licenses></licenses>
<!-- 組織信息 -->
<organization></organization>
<!-- 依賴集,用於配置依賴 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>

<!-- 依賴范圍:這個jar包只在范圍內生效,范圍外引用會報錯,這里讓junit只在test時被依賴。
其他一些情況,如:servlet-api.jar,在編譯階段需要引用,而在服務器運行階段則不需要引用,就可以使用scope-->
<scope>test</scope>

<!-- 默認為false,子項目將會繼承,true時子項目並需顯式引用 -->
<optional>false</optional>

<!-- 排除依賴列表:用於去除傳遞依賴等,在后面會詳細介紹-->
<exclusions>
<exclusion></exclusion>
</exclusions>

</dependency>
</dependencies>

<!-- 依賴管理
為依賴進行統一管理,如果在父項目中聲明此標簽時,在子項目中不需聲明,確保父子項目依賴版本一致;
如子項目需要不同版本的依賴,只需在子項目中進行聲明即可,將會覆蓋父項目中的聲明。
-->
<!--
<dependencyManagement>
<dependencies>
<dependency></dependency>
</dependencies>
</dependencyManagement>
-->

<!--配置構建時的屬性-->
<build>
<plugins></plugins>
</build>

<!-- 指定父模塊 -->
<!-- <parent></parent> -->

<!-- 用於聚合編譯多個maven模塊 -->
<modules></modules>
</project>

9. maven依賴 (范圍、傳遞、沖突)

范圍:   

    首先要知道,maven中提供了三種classpath:編譯、測試、運行
    scope標簽
      -compile 默認,編譯測試運行均有效,會傳遞
      -provided 在編譯和測試時有效,如servletAPI可以加入,不傳遞
      -runtime 在測試和運行時有效,如JDBCAPI可以加入
      -test 在測試時有效,如junit可以加入
      -system 在編譯和測試時有效,與本機系統相關聯,移植性差,在系統中以外部jar包的形式引入,不會在倉庫中查找
      -import 導入,只能用在dependecyManagement中,表示從其他pom中導入dependecy的配置

  傳遞:

    先來看看什么是傳遞依賴,比如現在有這么個情況:

    C依賴B、B依賴A——C→B→A,那么此時C也會依賴A且會包含A中的依賴,這就是傳遞依賴。接下來我們通過一個例子來詳細了解依賴及如何消除傳遞依賴:

    現有ABC三個項目:

    

  A中額外依賴了一個commons-io的jar包:

  

  B中對A進行依賴:

  

  C中對B進行依賴:

  

  保存之后可以看到,C中不但包含B,還包含A和A依賴的common-io:

  

  那么如何消除傳遞依賴呢,這里就使用到<exclusion>標簽了,在C中配置依賴B的地方加入以下內容:

  

  保存后就可以看到,C中關於A的依賴消失了,傳遞依賴的問題就解決了。

   

沖突:

    假設現在有這么個情況:A依賴common-io的2.4版本,B依賴common-io的2.5版本,C依賴A、B,那么此時C中的common-io是哪個版本的?

    這就是依賴沖突,在maven中應對依賴沖突有兩種解決方式:短路優先,先聲明優先

      先聲明優先:顧名思義,在pom中,寫在配置文件上面的優先,比如此時A的依賴配置在B之上,那C中就為2.4版本的common-io。

      短路優先:優先選擇依賴路徑較短的一端。假設現在多出一個D,依賴情況改為D依賴B,C依賴A、D——C→A、C→D→B,那么這里就是A的依賴路徑比較短,所以為2.4版本。

10. 聚合&繼承

     

聚合:

    試想一下這樣的情況,在一個項目中,分模塊使用了maven,那么可能在這個項目中會有五六個,或者更多的maven項目存在。如果此時需要編譯或測試要怎么辦呢,進入每個maven項目中進行mvn compile么,那就要執行五六次的compile命令,十分繁瑣,這里就可以用maven的聚合來解決這個問題。

    現有ABC三個工程,那么我們使用一個新的工程D,來聚合他們,以后只要對D進行編譯即可對三個工程同時進行編譯。使用module標簽進行聚合:

     

  <modules>
    <!--這里的路徑是基於D項目的pom.xml路徑,module標簽內為指向其他項目的pom文件的路徑
        這里我的ABCD項目在同一個文件夾內,那么從D內的pom中,通過../項目名,來找到其他項目的pom.xml-->
      <module>../A</module>
      <module>../B</module>
      <module>../C</module>
  </modules>

繼承:

    另一種情形,如果多個maven項目具有相同的依賴時或配置時,那么應該如何處理呢?這里就用到繼承的概念,在maven中使用<parent>標簽來進行繼承,下面通過一個例子來看一下:

    首先建立一個項目,命名為parent,在parent的pom文件聲明一個common-io的依賴,不過這里用到了dependencyManagement:

 

<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>cn.edu</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>parent</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

    <dependencyManagement>
        <!-- 在這里聲明的依賴可以被子項目繼承引用 -->
        <dependencies>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
可以看到,雖然我們在父項目中配置了依賴,但是卻不會在父項目中被引用:

 

  在子項目B中,配置繼承parent並使用parent中的common-io版本:

<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>cn.edu</groupId>
    <artifactId>B</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>B</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- 在parent標簽中使用父項目的坐標進行配置 -->
     <parent>
          <groupId>cn.edu</groupId> 
          <artifactId>parent</artifactId> 
        <version>0.0.1-SNAPSHOT</version> 
    </parent>
    
    <dependencies>
        <!-- 此處使用依賴時,就不需聲明版本 -->
        <dependency> 
            <groupId>commons-io</groupId> 
            <artifactId>commons-io</artifactId> 
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

配置后保存即可看到,此處的依賴版本即為父項目中的版本:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM