https://github.com/laker1/maven-learning-notes 

一、Maven下載:http://maven.apache.org/download.cgi
二、外掛目錄結構:
bin目錄:包含mvn的執行指令碼,在命令列中用mvn可呼叫
boot目錄:包含一個類載入器的框架,Maven使用它來載入主流類庫
conf目錄:配置檔案目錄,常用的有settings.xml
lib目錄:依賴類庫

三、配置環境變數:
M2_HOME:D:\JAVA\apache-maven-3.5.4
Path:%M2_HOME%\bin;
驗證:命令列下輸入:mvn -v

四、maven專案的目錄結構:
src
    -main
        -java
            -package
    -test
        -java
            -package
    resources
pom.xml

五、pom.xml檔案
可採用struts的lib目錄下struts2-core-2.2.3.jar包解壓後的META-INF/maven/org.apache.struts/struts2-core/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/maven-v4_0_0.xsd">
    // 基本4要素
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.imooc.maven01</groupId> // 專案的包名
    <artifactId>maven01-model</artifactId> // 模組名
    <version>0.0.1SNAPSHOT</version> // 版本名
    
    <dependencies>
        <dependency>  // 從中央倉庫新增junit依賴
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>  // 從本地倉庫新增jar包依賴
            <groupId>com.imooc.maven02</groupId>
            <artifactId>maven02-model</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    
</project>

六、常用命令
編譯:mvn compile
測試:mvn test
打包:mvn package
刪除:mvn clean   刪除target(包含編譯的位元組碼檔案和測試報告),但不刪除本地倉庫
安裝:mvn install 安裝jar包到本地倉庫中(包含了compile和package過程)


用外掛生成maven專案目錄結構:
方式一:mvn archetype:generate 自動生成maven目錄結構(需按提示錄入選項)
方式二:mvn archetype:generate -DgroupId=com.imooc.maven04 -DartifactId=maven04-demo -Dversion=0.0.1-SNAPSHOT -Dpackage=com.imooc.maven04.demo

groupId表示組織名(公司網址反寫+專案名)
artifactId表示專案名(專案名-模組名)
version表示版本號
package程式碼所存在的包名


<!--設定映象中央倉庫為阿里雲-->
<mirror>
    <id>alimaven</id>
    <mirrorOf>central</mirrorOf>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>

<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

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

七、maven中的座標和倉庫

構件:任何一個依賴、外掛、專案構件輸出都可以稱之為構件,所有構件都通過座標作為其唯一標識。
maven中,任何構件座標都是由groupId、artifactId、version來唯一標識的
建議建立maven專案時,java的包名應該與pom.xml中groupId和artifactId命名相吻合

倉庫:用來管理和存放所有專案的構件和依賴。可分兩種:本地倉庫和遠端倉庫(包括中央倉庫和其它映象倉庫)
如果本地倉庫找不到就會去中央倉庫查詢,查詢到依賴就會下載到本地倉庫供我們使用
一旦設定映象倉庫,所有對原倉庫的訪問都將轉到映象倉庫訪問,原預設倉庫將不會再被訪問

超級pom.xml:在maven的安裝目錄下/lib/maven-model-builder-3.5.4.jar包
解壓後在 org\apache\maven\model 目錄中有一個pom.xml,所有maven專案都會繼承這個超級pom
它含有中央倉庫的地址

更改本地倉庫預設位置:
預設:【本地倉庫目錄 ———— c:/user/使用者名稱/.m2/repository】
修改本地倉庫預設位置方法:
在maven安裝目錄找到conf/settings.xml檔案,新增修改如下:
<localRepository>D:/JAVA/repo</localRepository>
建議:將該檔案修改後儲存到本地倉庫中,以防maven升級後設置被覆蓋

八、eclipse配置Maven專案
preference->Java->Installed JREs選擇自已下載的JDK
          ->Maven->Installations選擇自己下載的Maven
          ->Maven->User Settings選擇自已設定的目錄(不一定要用在maven安裝目錄的conf下那個)
File->New->Maven Project新建一個maven專案
滑鼠在專案的pom.xml檔案上右鍵->Run As->Maven build...彈出框中:Goals框中輸入命令 compile或package即可編譯或生成包    
      
九、maven三個生命週期
clean:清理專案
    pre-clean    clean    post-clean
default:構建專案(最核心)
    compile test package install
site:生成專案站點
    pre-site    site    post-site    site-deploy

十、關於maven外掛示例:http://maven.apache.org/plugins/maven-source-plugin/
build中使用的外掛是執行命令用的,也放在中央倉庫中,其座標定位方式和dependency一樣
jar-no-fork主要用來建立專案的原始碼jar包,繫結到生命週期package後,執行package,呼叫目標,生成source.jar的原始碼包
  <build>  
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-source-plugin</artifactId>
              <version>3.0.1</version>
              <executions>
                  <execution>
                      <phase>package</phase>
                      <goals>
                          <goal>jar-no-fork</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      </plugins>
  </build>
★可能遇到的問題:參考 https://blog.csdn.net/lslk9898/article/details/73836745
1、Preference->Java->Installed JREs應選擇jdk目錄(不是jre目錄)  
2、Build Path->Configure Build Path->Libraries->JRE System Library
    ->"Edit"->Alternate JRE:選擇第1步中的jdk目錄
3、Maven->Update project(應該放在第2步,因為更新maven後,原第2步設定會被還原)

十一、pom.xml解析
<groupId></groupId>
<artifactId></artifactId>
<version></version> // 大版本號.分支版本號.小版本號
                    // snapshot快照  alpha測試  beta公測  release穩定  ga正式釋出
<packaging>jar</packaging>
// 打包型別預設是jar,還有war,zip,pom等型別
<name></name> // 專案描述名
<url></url> // 專案地址
<description></description>
<developers></developers>
<licenses></licenses>
<organization></organization>
<dependencies>
    <dependency>
        ...座標3要素
        <type></type>
        <scope>test</scope> // 指依賴範圍,test表示用於測試範圍
        <optional></optional>
// 設定依賴是否可選,預設是false,表示子專案是繼承的,若為true,子專案必須顯式引用該依賴
        <exlusions> // 排除依賴傳遞的列表
            <exclusion></exclusion>
        </exclusions>
    </dependency>
</dependencies>
<dependencyManagement> // 依賴管理座標元件的版本號
    <dependencies>
        <dependency></dependency>
// 不會被執行(不會被引入到實際的依賴),主要用來定義在父模組中,讓子模組來繼承
    </dependencies>
</dependencyManagement>
<build> // 主要用來對構件的行為提供外掛支援
    <plugins>
        <plugin>
            ...座標3要素
            <executions></executions> // 行為定義管理
        </plugin>
    </plugins>
</build>
<parent>...座標3要素</parent> // 通常用於指定當前子模組對父模組的pom的繼承
<modules> // 用來聚合執行多個maven項(指定多個模組一起編譯)
    <module></module>
</modules>

十二、依賴範圍
共有6種,
compile: 預設範圍,編譯測試執行都有效
provided: 在編譯和測試時有效
runtime: 在測試和執行時有效
test: 只有測試時有效,比如junit
system: 同provided,但與本機系統相關聯,可移植性差
import: 只能用於<dependencyManagement>標籤中,表示從其它pom中繼承過來的依賴

十三、依賴傳遞與依賴衝突
1、短路優先
2、如果路徑長度相同,則誰先宣告,先解析誰


十四、聚合和繼承

A、聚合操作:
新建hongxing-aggregation的maven專案(供自身用)
1、pom.xml中的<package>改為pom型別
2、新增<modules>標籤
<modules>
      <module>../hongxing-bge</module>
      <module>../hongxing.nge</module>
      <module>../hongxing-shanji</module>
  </modules>
3、Run as->maven build->compile

B、繼承操作:
新建hongxing-parent的maven專案(供子專案用)
1、父專案pom.xml中的<package>改為pom型別
2、父專案中新增<dependencyManagement>標籤管理所有子專案的依賴(直接包裹原<dependencies>標籤即可)
注意:並不實現引入,因此子專案仍需要顯式宣告需要用到的依賴
3、父專案中可統一管理子專案依賴的版本屬性:
a、將父專案的pom.xml檔案中:<properties>中新增屬性<junit.version>3.8.1</junit.version>,
將junit的依賴的版本屬性替換為<version>${junit.version}</version>,統一管理版本
b、將子專案的junit依賴中的<version>和<scope>刪除,保留<groupId>和<artifactId>即可,
這樣子專案就繼承了父專案的版本,如果子專案需要另外的一個版本,只需要宣告<version>就可
4、子專案中新增<parent>標籤指明父專案的座標:
<parent>
    <groupId>com.hongxing</groupId>
    <artifactId>hongxing-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</parent>
5、將父專案中的src/test/java目錄刪除掉,以免報錯(因為不需要測試目錄)


十五、補充部分
1、當子專案宣告一個依賴(必須描述groupId和artifactId資訊),如果groupid和artifactId以外的一些資訊沒有被描述,則通過groupId和artifactId匹配到父類的依賴,並使用這裡的依賴資訊。

2、POM是最簡單的打包型別。不像一個JAR,SAR,或者EAR,它生成的構件只是它本身。
沒有程式碼需要測試或者編譯,也沒有資源需要處理。打包型別為POM的專案的預設目標
生命週期階段        目標
package             site:attach-descriptor
install             install:install
deploy              deploy:deploy
注意:pom 專案裡沒有java程式碼,也不執行任何程式碼,只是為了聚合工程或傳遞依賴用的。

3、dependencyManagement裡只是宣告依賴,並不實現引入,因此子專案需要顯式的宣告需要用的依賴。
這樣做的好處就是:如果有多個子專案都引用同一樣依賴,則可以避免在每個使用的子專案裡都宣告一個版本號,這樣當想升級或切換到另一個版本時,只需要在頂層父容器裡更新,而不需要一個一個子專案的修改 ;另外如果某個子專案需要另外的一個版本,只需要宣告version就可。

4、其實繼承的作用遠不止如此,子專案繼承父專案的東西還很多,如下:
groupId :專案組 ID ,專案座標的核心元素;  
version :專案版本,專案座標的核心元素;  
description :專案的描述資訊;  
organization :專案的組織資訊;  
inceptionYear :專案的創始年份;  
url :專案的 url 地址  
develoers :專案的開發者資訊;  
contributors :專案的貢獻者資訊;  
distributionManagerment :專案的部署資訊;  
issueManagement :缺陷跟蹤系統資訊;  
ciManagement :專案的持續繼承資訊;  
scm :專案的版本控制資訊;  
mailingListserv :專案的郵件列表資訊;  
properties :自定義的 Maven 屬性;  
dependencies :專案的依賴配置;  
dependencyManagement :醒目的依賴管理配置;  
repositories :專案的倉庫配置;  
build :包括專案的原始碼目錄配置、輸出目錄配置、外掛配置、外掛管理配置等;  
reporting :包括專案的報告輸出目錄配置、報告外掛配置等。