Maven 基本概念

1 依賴

1.1 denpendency包含的元素

名稱 作用 備注
groupId 當(dāng)前Maven項(xiàng)目隸屬的實(shí)際項(xiàng)目 基本坐標(biāo)
artifactId 實(shí)際項(xiàng)目中的一個(gè)Maven項(xiàng)目模塊 基本坐標(biāo)
version 版本號 基本坐標(biāo)
type 依賴的類型,對應(yīng)于項(xiàng)目坐標(biāo)定義的packaging(巨) jar, war, pom,默認(rèn)是jar
scope 依賴的范圍 compile(編譯依賴范圍), test(測試依賴范圍), provided(已提供依賴范圍), runtime(運(yùn)行時(shí)依賴范圍), system(系統(tǒng)依賴范圍), import(導(dǎo)入依賴范圍), 默認(rèn)是compile
optional 標(biāo)記依賴是否可選 可選的依賴不能被依賴傳遞
exclusions 依賴排除 一個(gè)exclusions可以包含一個(gè)或者多個(gè)exclusion子元素,即排除一個(gè)或者多個(gè)傳遞性依賴

1.2 依賴范圍 scope

名稱 compile test runtime 說明
compile 對compile, test, runtime三個(gè)階段都有效
test 只在test階段有效
runtime 只在runtime階段有效
provided compile和test階段有效
system 該依賴和本機(jī)系統(tǒng)綁定,所以必須使用systemPath元素顯示地指定依賴文件的路徑,使用這個(gè)依賴范圍會造成構(gòu)建的不可移植性。
import dependencyManagement元素下才有用,該范圍的依賴通常指向一個(gè)pom,作用是把目標(biāo)pom中的dependencyManagement配置導(dǎo)入到當(dāng)前的pom,并且type配置為pom

java程序有三種classpath,分別是compile classpath,test classpath,runtime classpath,如上表不同的依賴范圍支持不同的classpath

假設(shè)A依賴于B,B依賴于C,我們說A對于B是第一直接依賴,B對于C是第二直接依賴,A對于C是傳遞性依賴

如下圖,最左邊一列表示第一直接依賴范圍,最上面一行表示第二直接依賴范圍,中間交叉單元格表示傳遞性依賴范圍。


依賴范圍影響傳遞性依賴

可以用mvn dependency:tree,可以看到各個(gè)依賴的依賴傳遞以及依賴范圍

[INFO] com.sankuai.sjst.crm:crm-common:jar:1.0.0-SNAPSHOT
[INFO] +- org.jmockit:jmockit:jar:1.9:test
[INFO] +- junit:junit:jar:4.12:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.springframework:spring-test:jar:4.2.6.RELEASE:test
[INFO] |  \- org.springframework:spring-core:jar:4.2.6.RELEASE:compile
[INFO] +- com.fasterxml.jackson.core:jackson-core:jar:2.1.0:compile
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.1.0:compile
[INFO] +- com.fasterxml.jackson.core:jackson-annotations:jar:2.1.0:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] +- org.springframework:spring-context:jar:4.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.2.6.RELEASE:compile
[INFO] |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  +- org.springframework:spring-beans:jar:4.2.6.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:4.2.6.RELEASE:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.4:compile
[INFO] +- commons-collections:commons-collections:jar:3.2.2:compile
[INFO] +- commons-io:commons-io:jar:2.3:compile
[INFO] +- com.meituan.inf:xmd-log4j2:jar:1.1.3:compile
[INFO] |  +- com.meituan.inf:xmd-common-log4j2:jar:1.1.2:compile
[INFO] |  |  \- org.slf4j:jcl-over-slf4j:jar:1.7.2:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.7.2:compile
[INFO] |  +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.3:compile
[INFO] |  +- org.apache.logging.log4j:log4j-api:jar:2.3:compile
[INFO] |  +- org.apache.logging.log4j:log4j-core:jar:2.3:compile
[INFO] |  \- org.apache.logging.log4j:log4j-1.2-api:jar:2.3:compile

1.3 依賴原則

1.路徑最近者優(yōu)先
2.第一聲明者優(yōu)先

2 倉庫

maven倉庫分類

一個(gè)構(gòu)件只有在本地倉庫中才能由其他Maven項(xiàng)目使用,構(gòu)件可以從遠(yuǎn)程倉庫中下載,也可以將本地項(xiàng)目的構(gòu)件install到本地的Maven項(xiàng)目中。
settings.xml的<localRepository>:定義本地倉庫的地址

2.1依賴查找的順序

① 在本地倉庫中搜索,如果找不到,執(zhí)行②,如果找到了則執(zhí)行其他操作。
② 在中央倉庫中搜索,如果找不到,并且有一個(gè)或多個(gè)遠(yuǎn)程倉庫已經(jīng)設(shè)置,則執(zhí)行步驟 ④,如果找到了則下載到本地倉庫中已被將來引用。
③ 如果遠(yuǎn)程倉庫沒有被設(shè)置,Maven 將簡單的停滯處理并拋出錯(cuò)誤(無法找到依賴的文件)。
④ 在一個(gè)或多個(gè)遠(yuǎn)程倉庫中搜索依賴的文件,如果找到則下載到本地倉庫已被將來引用,否則 Maven 將停止處理并拋出錯(cuò)誤(無法找到依賴的文件)。

2.2 settings.xml 和pom.xml中倉庫信息設(shè)置

依賴的下載與部署的倉庫是在pom.xml文件中的<distributionManagement>和<repository>設(shè)置的,通常訪問這些倉庫是需要認(rèn)證的,認(rèn)證信息在settings.xml<server>元素中。
pom.xml

<distributionManagement>
      <repository>
         <id>xxx-nexus-releases</id>
         <name>xxx Nexus Repository</name>
        <url>http://maven.xxx.com/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>xxx-nexus-snapshots</id>
            <name>xxx Nexus Repository</name>
            <url>http://maven.xxx.com/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
 </distributionManagement>

在settings.xml中<server>元素的id必須與pom.xml中需要認(rèn)證的<repository>的id完全一致。id將認(rèn)證信息和倉庫聯(lián)系在一起了。

 <server>
    <id>xxx-nexus-releases</id>
    <username>xxx</username>
    <password>yyyy</password>
 </server>
 <server>
    <id>xxx-nexus-snapshots</id>
    <username>xxx</username>
    <password>yyy</password>
</server>

pom.xml中設(shè)置了兩個(gè)倉庫,一個(gè)是release版本的倉庫,一個(gè)是snapshots,如果release倉庫Deployment Policy是“Disable
Redeploy”,那么release版本是不允許覆蓋的。
所以當(dāng)同樣的release版本號二次發(fā)布的時(shí)候會報(bào)錯(cuò),錯(cuò)誤提示類似“Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project crm-onlinepay-client: Failed to deploy artifacts: Could not transfer artifact com.xxx.yyy:crm-onlinepay-client:jar:1.0.1 from/to xxx-nexus-releases (http://maven.xxx.com/nexus/content/repositories/releases/): Failed to transfer file: http://maven.xxx.com/nexus/content/repositories/releases/com/xxx/yyy/crm-onlinepay-client/1.0.1/crm-onlinepay-client-1.0.1.jar. Return code is: 400, ReasonPhrase: Bad Request. -> [Help 1]”

Maven2部署構(gòu)件到Nexus時(shí)出現(xiàn)的Failed to transfer file錯(cuò)誤 @周路敏

3 Maven模塊的聚合與繼承

<modules> 聲明聚合 為了快速構(gòu)建項(xiàng)目
<parent>聲明繼承 為了消除重復(fù)配置
我的onlinepay項(xiàng)目結(jié)構(gòu)

crm-onlinepay

最外面層的pom.xml是聚合pom,他的packaging方式必須是pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         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>
    <parent>
        <groupId>com.xxx.yyyy.crm</groupId>
        <artifactId>crm-parent</artifactId>
        <version>1.0.4</version>
    </parent>

    <groupId>com.xxx.yyyy</groupId>
    <artifactId>crm-onlinepay</artifactId>
    <version>1.0.1</version>
    <packaging>pom</packaging>
    <name>${project.artifactId}</name>

    <properties>
        <project-client.version>1.0.1</project-client.version>
        <project-web.version>1.0.1</project-web.version>
    </properties>

    <distributionManagement>
        <repository>
            <id>xxxx-nexus-releases</id>
            <name>xxxx Nexus Repository</name>
            <url>http://maven.xxx.com/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>xxxx-nexus-snapshots</id>
            <name>xxx Nexus Repository</name>
            <url>http://maven.xxx.com/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>

    <modules>
        <module>crm-onlinepay-client</module>
        <module>crm-onlinepay-web</module>
    </modules>
</project>

onlinepay-client的pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xxx.yyyy</groupId>
        <artifactId>crm-onlinepay</artifactId>
        <version>1.0.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>crm-onlinepay-client</artifactId>
    <version>${project-client.version}</version>
    <packaging>jar</packaging>
    <name>${project.artifactId}</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.sankuai.sjst.crm</groupId>
            <artifactId>crm-common</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}-${project.version}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-archetype-plugin</artifactId>
                <version>2.2</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

    </build>
</project>

onlinepay-web的pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xxx.yyyy</groupId>
        <artifactId>crm-onlinepay</artifactId>
        <version>1.0.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>crm-onlinepay-web</artifactId>
    <packaging>war</packaging>
    <name>${project.artifactId}</name>
    <version>${project-web.version}</version>
.....
</project>
聚合和繼承

3.3 反應(yīng)堆

所有模塊組成的一個(gè)構(gòu)建結(jié)構(gòu)是反應(yīng)堆,反應(yīng)堆的順序與模塊間的繼承關(guān)系和聲明順序有關(guān),如果模塊間不存在繼承關(guān)系,則反應(yīng)堆的構(gòu)建順序是聲明順序,如果存在繼承關(guān)系,則首先構(gòu)建父模塊。
crm-onlinepay-client和crm-onlinepay-web是子模塊,crm-onlinepay是父模塊


項(xiàng)目反應(yīng)堆構(gòu)建順序

剪裁反應(yīng)堆
-am, --alse-make 同時(shí)構(gòu)建依賴于所列模塊的模塊
-amd, -alse-make-dependents 同時(shí)構(gòu)建依賴于所列模塊的模塊
-pl, --projects <arg> 構(gòu)建指定的模塊,模塊間用逗號分隔
-rf, -resume-from <arg> 從指定的模塊恢復(fù)反應(yīng)堆,也就是說從哪里開始構(gòu)建

3.4 pom中可繼承的元素

Maven繼承的目的是為了消除重復(fù),所以pom中大量的元素是可以被繼承的。

groupId:項(xiàng)目組ID,項(xiàng)目坐標(biāo)的核心元素
version: 項(xiàng)目版本, 項(xiàng)目坐標(biāo)的核心元素
description: 項(xiàng)目的描述信息
organization: 項(xiàng)目的組織信息
inceptionYear: 項(xiàng)目的創(chuàng)始年份
url: 項(xiàng)目的URL地址
developers: 項(xiàng)目開發(fā)者信息
contributors: 項(xiàng)目的貢獻(xiàn)者信息
distributionManagement: 項(xiàng)目的部署配置
issueManagement: 項(xiàng)目的缺陷跟蹤系統(tǒng)信息
ciManagement: 項(xiàng)目的持續(xù)集成系統(tǒng)信息
scm: 項(xiàng)目的系統(tǒng)信息
mailingLists: 項(xiàng)目的郵件列表信息
properties: 自定義的maven屬性
dependencies: 項(xiàng)目的依賴配置
dependencyManagement: 項(xiàng)目的依賴管理配置
repositories: 項(xiàng)目的倉庫配置
build: 包括項(xiàng)目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等
reporting: 包括項(xiàng)目的報(bào)告輸出目錄配置、報(bào)告插件配置等

所以crm-onlinepay項(xiàng)目會繼承crm-parent里面的依賴等信息

4 靈活的構(gòu)建

Maven提供屬性,資源過濾和profile三種方式進(jìn)行靈活的構(gòu)建

4.1Maven屬性

1.內(nèi)置屬性
${basedir}表示項(xiàng)目根目錄,${version}表示項(xiàng)目版本
2.POM屬性
(使用pom屬性可以引用到pom.xml文件對應(yīng)元素的值)
${project.build.directory}表示主源碼路徑;
${project.build.sourceEncoding}表示主源碼的編碼格式;
${project.build.sourceDirectory}表示主源碼路徑;
${project.build.finalName}表示輸出文件名稱;
${project.version}表示項(xiàng)目版本,與${version}相同;
3.自定義屬性
在pom.xml文件的<properties>標(biāo)簽下定義的Maven屬性
4.settings.xml文件屬性
(與pom屬性同理,用戶使用以settings.開頭的屬性引用settings.xml文件中的XML元素值)
${settings.localRepository}表示本地倉庫的地址;
5.Java系統(tǒng)屬性
(所有的Java系統(tǒng)屬性都可以使用Maven屬性引用)
使用mvn help:system命令可查看所有的Java系統(tǒng)屬性;
System.getProperties()可得到所有的Java屬性;
${user.home}表示用戶目錄;
6.環(huán)境變量屬性
(所有的環(huán)境變量都可以用以env.開頭的Maven屬性引用)
使用mvn help:system命令可查看所有環(huán)境變量;
${env.JAVA_HOME}表示JAVA_HOME環(huán)境變量的值;

4.2 資源過濾

maven-resources-plugin的默認(rèn)行為是將項(xiàng)目主資源文件復(fù)制到主代碼編譯輸出目錄中,將測試資源文件復(fù)制到測試代碼編譯輸出目錄中,如果開啟了資源過濾,那么可以讀取資源目錄下的文件內(nèi)容,即解析資源文件中的maven屬性。
如果是web資源,則是通過maven-resources-plugin處理。

4.3 profile

可以根據(jù)環(huán)境不同選擇不同的資源配置,<activeByDefault>表示默認(rèn)激活的環(huán)境配置資源。

<profiles>
    <profile>
        <id>local</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <conf-dir>local</conf-dir>
        </properties>
    </profile>
    <profile>
        <id>dev</id>
        <properties>
            <conf-dir>dev</conf-dir>
        </properties>
    </profile>
    <profile>
        <id>beta</id>
        <properties>
            <conf-dir>beta</conf-dir>
        </properties>
        </profile>
    <profile>
        <id>miniflow</id>
        <properties>
            <conf-dir>miniflow</conf-dir>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <conf-dir>test</conf-dir>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <conf-dir>prod</conf-dir>
        </properties>
    </profile>
    <profile>
        <id>staging</id>
        <properties>
            <conf-dir>staging</conf-dir>
        </properties>
    </profile>
</profiles>
profiles

可以通過命令行參數(shù) -P 加上profile的id來激活profile,多個(gè)id之間用逗號分隔。

settings.xml文件中也會有profile的配置,如果一個(gè)settings.xml中的profile被激活,它的值會覆蓋任何其它定義在pom.xml中帶有相同id的profile。
maven全局配置文件settings.xml詳解 @靜默空虛

5 超級POM

Maven約定大約配置,在$MAVEN_HONE/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路徑下存在超級pom。每個(gè)Maven項(xiàng)目都會繼承這個(gè)超級pom,類似java中的object類,
超級pom聲明了倉庫等信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,649評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,281評論 6 342
  • |-1-更新內(nèi)容[6.從倉庫解析依賴的機(jī)制(重要)] 1Maven倉庫作用 倉庫用來存儲所有項(xiàng)目使用到構(gòu)件,在ma...
    zlcook閱讀 6,464評論 0 25
  • 前言什么是 POMQuick Overview POM 常用元素 pom.xml 完整注釋 參考 0 前言 什么是...
    阿父閱讀 12,766評論 1 36
  • 當(dāng)前,JVM生態(tài)圈主要的三大構(gòu)建工具: Apache Ant(帶著Ivy) Maven Gradle 對于剛開始接...
    清楓_小天閱讀 5,986評論 1 13

友情鏈接更多精彩內(nèi)容