Maven項目管理

maven快速入門

Maven是基于項目對象模型(POM),可以通過一小段描述信息來管理項目的構建、報告和文檔的軟件項目管理工具。

maven安裝配置

下載好maven后,需要配置環境變量。

  1. 設置JAVA_HOMED:\program files\Java\jdk1.8.0_91, path添加%JAVA_HOME%\bin
  2. 新建M2_HOME,指向maven安裝目錄:D:\app\apache-maven-3.3.9
  3. 修改path,添加%M2_HOME%\bin
  4. 在命令行中輸入mvn -v看看是否輸出正確。

maven helloworld案例

maven目錄結構結構

src
    -main
        -java
            -package
    -test
        -java
            -package
    -resources

按照上面的目錄結構創建目錄,package目錄先不要創建package。

分別新建

package lx.maven.model;

public class HelloWorld{
    public String sayHello() {
        return "Helo world!";
    }
}

和測試

package lx.maven.model;

import org.junit.*;
import org.junit.Assert.*;

public class HelloWorldTest{
    @Test
    public void testHello() {
        Assert.assertEquals("Hello world!", new HelloWorld().sayHello());
    }
}

這里需要注意的是分別新建包。

然后需要新建pom.xml,保存在項目根目錄下。

<?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>lx.maven</groupId>
    <artifactId>maven01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>

</project>

說明:

  • modelVersion:固定,不管
  • groupId 項目的包名
  • artifactId 模塊名
  • version 版本,SNAPSHOT快照版本

編譯:mvn compile
運行測試用例:mvn test

運行后我們看到項目更目錄下創建了target文件夾,這個文件夾下面又有幾個子文件夾,分別是:

  • classes 生成的類文件字節碼
  • surefire-reports 測試報告

然后運行mvn package進行打包。打好的包在target根目錄下。

Maven核心知識

常用的構建命令

之前我們已經學習了以下命令:

  • mvn -v:查看maven版本
  • mvn compile: 編譯
  • mvn test: 測試
  • mvn package:打包

本節主要學習以下兩個命令:

  • mvn clean: 刪除target
  • mvn install: 安裝jar包到本地倉庫中

我們新建一個項目maven02

package lx.maven02.util;

import lx.maven.model.HelloWorld;

public class Speak{
    public String sayHi() {
        return new HelloWorld().sayHello();
    }
}
package lx.maven02.util;

import org.junit.*;
import org.junit.Assert.*;

public class SpeakTest{
    @Test
    public void testsayHi() {
        Assert.assertEquals("Hello world!", new Speak().sayHi());
    }
}
<?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>lx.maven02</groupId>
    <artifactId>maven02-util</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>

</project>

此時運行mvn compile會報錯,表示找不到對應的lx.maven.model包。之所以會這樣是因為我們需要講maven01的項目運行mvn install先安裝到本地倉庫,然后在maven02項目中添加依賴:

<dependency>
    <groupId>lx.maven</groupId>
    <artifactId>maven01</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

自動建立目錄骨架

之前一直手動創建很麻煩,maven提供了archetype插件,用于創建符合maven規定的目錄骨架。

我們先創建一個項目目錄maven03,然后在命令行輸入:

mvn archetype:generate

然后會讓我們選擇archetype版本,選擇最大的就好了,然后要求我們輸入groupId,我們輸入lx.maven03artifactId我們輸入maven03-service,version我們輸入1.0-SNAPSHOT.然后會要求我們輸入包名,不過會根據你之前輸入的groupId自動提供一個,我們直接回車就可以了。最后會讓我們確認信息,沒問題就回車。

還有一種方法是一次性設置所有參數:

mvn archetype:generate -DgroupId=lx.maven03 -DartifactId=maven04-demo -Dversion=1.0SNAPSHOT -Dpackage=lx.maven03.demo

maven中的坐標和倉庫

坐標:構件的唯一標識。groupId,artifactId,version構成了坐標的基本要素。

倉庫:管理項目依賴,分為兩種:

  • 本地倉庫
  • 遠程倉庫:如果本地倉庫找不到,會到maven的全球倉庫去找。

鏡像倉庫:打開maven/conf/settings.xml文件,在mirrors節添加:

<mirror>
     <id>maven.oschina.net</id>
     <mirrorOf>central</mirrorOf>
     <name>oschina maven mirror</name>
      <url>http://maven.oschina.net/content/groups/public</url>
   </mirror>

mirrorOf表示為哪個倉庫指定鏡像,默認是central,也可以使用*通配符。

現在看如何修改倉庫位置:
默認情況下,倉庫是在用戶文件夾下的.m2文件中,我們可以修改settings.xml的settings下的位置:

<localRepository>D:/mavenrepo</localRepository>

然后將settings.xml文件復制到d:/mavenrepo下,這樣以后要是修改maven版本就不用再次修改settings.xml.

maven的聲明周期和插件

完整的項目構建過程包括:
清理、編譯、測試、打包、集成測試、驗證、部署
clean\compile\test\package\install
maven聲明周期:

  • clean 清理項目
  • default 構建項目
  • site 生成項目站點

對于clean清理項目

  • pre-clean 執行清理前的工作
  • clean 清理上一次構建生成的所有文件
  • post-clean 執行清理后的文件

default構建項目(最核心)
compile test package install都屬于default階段

site生成項目站點

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

現在加入我們要添加插件source,讓打包時同時打包源碼。我們修改pom.xml,加入:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

說明:

  • plugin的phase表明階段
  • goal表示目標

具體請看apache官方文檔。

然后運行mvn clean package看到會生成源碼的jar包。

pom.xml常用元素介紹

pom.xml用于項目描述、組織管理、依賴管理和項目信息的管理。下面我們來介紹一下常用元素。

<?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">
    <!--指定了當前的POM版本-->
    <modelVersion>4.0.0</modelVersion>
    <!--主項目標識:反寫公司網址+項目名-->
    <groupId></groupId>
    <!--項目名+模塊名-->
    <artifactId></artifactId>
    <!--當前版本項目本:大版本號.分支版本號.小版本號;SNAPSHOT:快照,ALPHA:內部測試,BETA:公測,RELEASE:穩定版,GA:正式發布-->
    <version>0.0.1-SNAPSHOT</version>
    <!--打包方式,默認為jar .war,zip,pom-->
    <packaging>jar</packaging>

    <!--項目描述名,產生文檔時使用-->
    <name>hi</name>
    <!--項目地址-->
    <url></url>
    <!--項目描述-->
    <description></description>
    <!--開發人員信息-->
    <developers></developers>
    <!--許可證信息-->
    <licenses></licenses>
    <!--組織信息-->
    <organization></organization>

    <!-- 依賴列表 -->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <type></type>
            <!-- 只在一個范圍內使用 -->
            <scope>test</scope>
            <!-- 設置依賴是否可選,默認為false,默認是繼承的 -->
            <optional></optional>
            <!-- 排除依賴傳遞列表。如果A依賴B,B依賴C,A就傳遞依賴C -->
            <exclusions>
                <exclusion>
                    <groupId></groupId>
                    <artifactId></artifactId>
                    <version></version>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <!-- 依賴的管理.不會實際被引入,主要用于定義在父模塊,用于子模塊繼承 -->
    <dependencyManagement>
        <dependencies>
            <dependency></dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <!-- 插件列表 -->
        <plugins>
            <plugin>
                <groupId></groupId>
                <artifactId></artifactId>
                <version></version>
            </plugin>
        </plugins>
    </build>

    <!-- 在子模塊中對父模塊POM的繼承 -->
    <parent></parent>
    
    <!-- 多模塊 -->
    <modules></modules>
</project>

依賴范圍

之前已經見過junit依賴:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>

我們平時在開發時,如果要使用某個框架就需要將該框架的jar包添加到項目的classpath中,maven為我們提供了3種classpath,分別是:

  • 編譯
  • 測試
  • 運行

所以scope就是用來指定依賴范圍的。maven官方文檔上說scope有六種取值:

  • compile:編譯,默認的范圍,編譯測試運行都有效
  • provided:測試和編譯時有效,運行時不會用
  • runtime:測試和運行時有效
  • test:測試,只在測試時有效
  • system:測試和編譯時有效,可移植性差,與本機想關聯
  • import:導入的范圍,只使用在dependencyManagement中,表示從其他的pom中導入dependency的配置

依賴傳遞

A依賴B,B依賴C,則就可以說A間接依賴C。

首先,我們在B中引入對C的依賴(C應該mvn compile install).

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <type></type>
    <!-- 只在一個范圍內使用 -->
    <scope>test</scope>
    <!-- 設置依賴是否可選,默認為false,默認是繼承的 -->
    <optional></optional>
    <!-- 排除依賴傳遞列表。如果A依賴B,B依賴C,A就傳遞依賴C -->
    <exclusions>
        <exclusion>
         <groupId></groupId>
         <artifactId></artifactId>
         <version></version>
        </exclusion>
    </exclusions>
</dependency>

有時我們需要指定JDK默認版本,在settings.xml中的profile配置版本。

依賴沖突

  1. 短路優先
    A->B-C-X(jar)A->D->X(jar),則A優先引用D所指向的X。
  2. 先聲明先優先
    如果路徑長度相同,則誰先聲明,先解析誰。

聚合和繼承

先來說聚合。

如果有多個項目,A\B\C,我們想要把他們聚合起來,一起安裝,我們新建一個項目D,修改它的pom.xml:

<modules>
    <module>../A</module>
    <module>../B</module>
    <module>../C</module>
</modules>

然后運行mvn clean install就能直接安裝A/B/C了。

再來說繼承。
在父pom中添加:

<!-- 指定類型為POM -->
<packaging>pom</packaging>
<properties>
    <!-- 定義變量 -->
    <junit.version>3.8.1</junit.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

在子POM中使用:

<parent>
    <groupId></groupId>
    <artifactId></artifactId>
    <version></version>
</parent>

使用maven構建web項目

我們使用maven創建一個web項目,然后發布到jetty中。

使用IDEA創建一個maven項目,選擇maven-archetype-webapp類型,GroupId輸入lx.webdemo,artifectId輸入webdemo
http://mvnrepository.com/ 中添加
我們打開pom.xml,添加Java Servlet API依賴,注意,servlet的f范圍是provided

<?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>lx.webdemo</groupId>
    <artifactId>webdemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <!--只在編譯時和測試時運行-->
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

然后添加Jetty maven plugin

<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">
  <modelVersion>4.0.0</modelVersion>
  <groupId>lx.webdemo</groupId>
  <artifactId>webdemo</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>webdemo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
      </dependency>
  </dependencies>
  <build>
    <finalName>webdemo</finalName>
      <plugins>
          <plugin>
              <groupId>org.eclipse.jetty</groupId>
              <artifactId>jetty-server</artifactId>
              <version>9.4.0.M0</version>
              <executions>
                  <execution>
                      <phase>package</phase>
                      <goals>
                          <goal>run</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      </plugins>
  </build>
</project>

然后運行mvn clean package即可。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容