1. 程式人生 > >Maven基礎入門與核心知識

Maven基礎入門與核心知識

Apache Maven是一個軟體專案管理和綜合工具。基於專案物件模型(POM)的概念,Maven可以從一箇中心資料片管理專案構建,報告和檔案。

Maven是一個專案管理和綜合工具。Maven提供了開發人員構建一個完整的生命週期框架。開發團隊可以自動完成專案的基礎工具建設,Maven使用標準的目錄結構和預設構建生命週期。

在多個開發團隊環境時,Maven可以設定按標準在非常短的時間裡完成配置工作。由於大部分專案的設定都很簡單,並且可重複使用,Maven讓開發人員的工作更輕鬆,同時建立報表,檢查,構建和測試自動化設定。

概括地說,Maven簡化和標準化專案建設過程。處理編譯,分配,文件,團隊協作和其他任務的無縫連線。 Maven增加可重用性並負責建立相關的任務。

安裝配置

安裝需要Java支援(JDK >= 1.7)。

下載壓縮包

解壓安裝

解壓壓縮包至目錄,我的安裝位置:D:\apache-maven-3.5.4

  • bin:mvn的執行指令碼
  • boot:mvn類載入器框架
  • conf:配置檔案目錄
  • lib:依賴類庫

配置環境變數

『計算機』-->『右鍵屬性』-->『高階系統設定』-->『環境變數』-->『系統變數』

MAVEN_HOME

PATH

依次確定,退出配置。

配置Maven

開啟Maven目錄,./conf/settings.xml

配置本地儲存庫

新增配置

<localRepository>D:/mavenRepository/repository</localRepository>

 localRepository 標籤包含的就是本地儲存庫的地址。

配置映象倉庫

由於中央儲存庫在國外,國內可能打不開,所以在 mirrors 標籤中新增阿里雲映象倉庫配置。

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

測試安裝

開啟CMD視窗,輸入命令: mvn -v 

出現以下內容,說明Maven安裝成功。

建立Maven專案

首先說明Maven約定的目錄結構:

├─ src
│ ├─ main          存放主程式
│ │ ├─ java        存放Java原始檔
│ │ ├─ resources   存放框架或其他工具的配置檔案
│ ├─ test          存放測試程式
│ │ ├─ java        存放Java測試的原始檔
│ │ ├─ resources   存放測試的配置檔案
├─pom.xml          Maven工程的核心配置

這裡我直接使用IntelliJ建立Maven專案。

這裡可以不勾選 create from archetype 直接建立,使用標準的模板(初始不做web測試,不需要使用此模板),這裡我選擇使用webapp模板(初始檔案建立,可以參考我下面的構建WEB專案)。

這裡在Properties中新增一個引數archetypeCatalog=internal

資訊輸入完後點擊Finish,至此Maven專案就建立完了,因為我們選擇的是webapp,所有有些Maven約定的目錄需要我們手動建立補全。

常用構建命令

maven01 - 編譯/測試

建立Maven專案maven01

配置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>com.maven01</groupId>
  <artifactId>maven01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven01 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

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

  <build>
    <finalName>maven01</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
View Code

在maven01/src/main/java建立包 com.maven01.model 

建立HelloWorld.java

package com.maven01.model;

public class HelloWorld {
    public String sayHello() {
        return "Hello World !!";
    }
}
View Code

在maven01/src/test/java建立包 com.maven01.model

建立HelloWorldTest.java

package com.maven01.model;

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

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

mvn compile  - 編譯

開啟CMD,跳轉當前位置至專案目錄。

執行命令: mvn compile 

第一次執行會下載很多資源。

出現BUILD SUCCESS說明編譯成功:

mvn test - 測試

執行命令: mvn test 

第一次運行同樣會下載依賴資源。

出現BUILD SUCCESS說明執行成功:

maven02 - 安裝/依賴

建立Maven專案maven02

配置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>com.maven02</groupId>
  <artifactId>maven02</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven02 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

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

  <build>
    <finalName>maven02</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
View Code

在maven02/src/main/java建立包 com.maven02.util

建立Speak.java

package com.maven02.util;

import com.maven01.model.HelloWorld;

public class Speak {
    public String sayHi() {
        return new HelloWorld().sayHello();
    }
}
View Code

在maven02/src/test/java建立包 com.maven01.util

建立SpeakTest.java

package com.maven02.util;

import org.junit.Assert;
import org.junit.Test;

public class SpeakTest {
    @Test
    public void testsayHi() {
        Assert.assertEquals("Hello World !!", new Speak().sayHi());
    }
}
View Code

這時我們使用編譯命令,嘗試編譯maven02會發現報錯:

mvn install - 安裝

跳轉碟符至maven01目錄

執行命令: mvn install

將maven01的jar包安裝到本地倉庫中 

重新配置maven02的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>com.maven02</groupId>
  <artifactId>maven02</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven02 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.maven01</groupId>
      <artifactId>maven01</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>maven02</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
View Code

重新編譯maven02

mvn dependency:tree - 檢視依賴

執行命令: mvn dependency:tree 

自動構建目錄

maven03 - 自動構建目錄

mvn archetype:generate - 按照提示進行選擇構建

建立資料夾maven03

跳轉碟符至maven03目錄

執行命令: mvn archetype:generate 

執行成功後會發現,目錄已經自動構建了出來:

├─maven0301-service
│  │  pom.xml
│  │
│  └─src
│      ├─main
│      │  └─java
│      │      └─com
│      │          └─maven0301
│      │              └─service
│      │                      App.java
│      │
│      └─test
│          └─java
│              └─com
│                  └─maven0301
│                      └─service
│                              AppTest.java

mvn archetype:generate - 帶參構建

跳轉碟符至maven03目錄

執行命令: mvn archetype:generate -DgroupId=com.maven0302 -DartifactId=maven0302-demo -Dversion=1.0-SNAPSHOT -Dpackage=com.maven0302.demo 

  • DgroupId:組織名
  • DartifactId:專案名-模組名
  • Dversion:版本號
  • Dpackage:程式碼所存在的包名

└─maven0302-demo
    │  pom.xml
    │
    └─src
        ├─main
        │  └─java
        │      └─com
        │          └─maven0302
        │              └─demo
        │                      App.java
        │
        └─test
            └─java
                └─com
                    └─maven0302
                        └─demo
                                AppTest.java

座標和倉庫

座標

在Maven中,任何一個依賴、外掛或者專案構建的輸出,都可以稱之為構件。

每個構建的位置,代表了一個座標。

pom.xml的依賴配置 groupId 、 artifactId 、 version 即可標識一個座標。

倉庫

關於倉庫的詳解大家可以參考此博文,介紹的很詳細!

倉庫預設配置位置:%MAVEN_HOME%\lib\maven-model-builder-x.x.x.jar\org\apache\maven\model\pom-4.0.0.xml

生命週期和外掛

關於生命週期和外掛的詳解大家可以參考此博文,介紹的很詳細!

依賴範圍

maven 專案不同的階段引入到classpath中的依賴是不同的,例如,編譯時,maven 會將與編譯相關的依賴引入classpath中,測試時,maven會將測試相關的的依賴引入到classpath中,執行時,maven會將與執行相關的依賴引入classpath中,而依賴範圍就是用來控制依賴於這三種classpath的關係。

在pom.xml依賴管理 dependency 有個設定依賴範圍的標籤 scope 

關於依賴範圍的設定,官方文件有詳細說明。

  • compile:預設的範圍,編譯測試執行都有效
  • provided:測試和編譯時有效
  • runtime:測試和執行時有效
  • test:測試時有效
  • system:測試和編譯時有效,與本機系統相關聯,可移植性差
  • import:匯入的範圍,它只使用在dependencyManagement中,表示從其它的pom中匯入dependecy的配置

依賴傳遞

我新建了三個專案分別為:dependA、dependB、dependC

它們的依賴關係為:dependC ----> dependB ----> dependA

dependA的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>com.maven.dependA</groupId>
    <artifactId>dependA</arti