Maven之POM文件

[TOC]

Maven之POM文件

Maven简介

Maven,单词源于九世纪的中欧,原意为致力于传道受业解惑的某一领域的专家。

Maven是构建java工程的主流工具,包括Java工程的结构化管理、编译、打包、发布、测试等。

Maven的特点

  • 提供简单的构建入口
  • 提供统一的构建体系
  • 提供完善的项目生命周期管理
  • 提供丰富的扩展插件
  • 提供便捷的依赖管理
  • 提供工程化管理的最佳实践

Maven的历史

Maven 1/2已不再更新,建议使用Maven 3+。
Maven 3相比Maven 2主要修复了多处bug和多处改进,比如优化的包依赖和插件依赖管理、优化的日志输出、支持并行编译、更为合理和标准的POM结构等。

  • 创建于2002年,至今已有3个大版本。最新版本为3.6.0,更新时间为2018-10-24。
  • 在Java编译和项目管理的工具发展史中也出现过其他一些身影,比如Ant(编译打包)、Ivy(依赖包管理)
    现在较新的Java项目管理工具如Gradle在Maven的基础上更进行了多处改进,比如去除繁杂的xml管理、更灵活的生命周期管理(Maven为固定生命周期流程 + 插件钩子)、多来源方式的依赖包(Maven必须为指定标准的Metadata,无论公仓还是私仓)。
  • 选择Maven一是考虑到生态环境的成熟度,此外还有参考其他团队的选型和学习成本的考量。
  • 更多Gradle与Maven的对比可以参考Gradle VS Maven

Maven VS MSBuild

MSBuild更像一个单纯的编译工具,虽然可以以自定义Task的方式在编译的各生命周期进行扩展,但是缺少依赖包的管理及自动化测试。在C#中与Maven的概念更为相似的是Maven的迁移项目NMaven。

Maven具有便捷的依赖包管理功能,在Java中Maven的地位相当于Python中的Pip、NodeJS中的npm、C#中的Nuget。
除此之外,Maven也囊括了项目的编译及发布等生命周期各环节的管理,与C#中的MSBuild比较主要有如下异同:

功能点 Maven MSBuild
编译
打包
发布
事件钩子
依赖包管理
自动化测试

Maven生命周期

  • validate: validate the project is correct and all necessary information is available
  • compile: compile the source code of the project
  • test: test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • package: take the compiled code and package it in its distributable format, such as a JAR.
  • integration-test: process and deploy the package if necessary into an environment where integration tests can be run
  • verify: run any checks to verify the package is valid and meets quality criteria
  • install: install the package into the local repository, for use as a dependency in other projects locally
  • deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

POM文件

POM = Project Object Model即项目对象模型,是Maven赖以对项目进行管理的依据。

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

POM文件基础配置

<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>org.codehaus.mojo</groupId>
  <artifactId>my-project</artifactId>
  <version>1.0</version>
</project>
  • model 4.0.0是目前Maven2&3唯一支持的解析版本,可以视其为固定节点。

POM文件之dependencies

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <type>jar</type>
      <scope>test</scope>
      <optional>true</optional>
      <exclusions>
        <exclusion>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    ...
  </dependencies>
  • 一个完整的Maven Coordinate由{groupdId}{artifactId}{version}[{classifier}][{type}]组成
  • 依赖的optional配置表示当其他项目引用本项目时,该项为非必须项
  • version的依赖可以根据实际情况指定范围,类似nuget中的package.json配置
    [图片上传失败...(image-d2a68a-1553006985017)]
  • exclusion支持通配符*,可以完全摒弃所有深层依赖自行管理

POM文件之properties

  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>
  • 属性实际是一种占位符;使用properties节点定义,使用${property}进行占位替换
  • Maven内置了一些默认属性可供直接使用,如{env.PATH}、{project.version}、${java.home}

POM文件之repositories

  <repositories>
    <repository>
      <releases>
        <enabled>false</enabled>
        <updatePolicy>always</updatePolicy>
        <checksumPolicy>warn</checksumPolicy>
      </releases>
      <snapshots>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        <checksumPolicy>fail</checksumPolicy>
      </snapshots>
      <id>codehausSnapshots</id>
      <name>Codehaus Snapshots</name>
      <url>http://snapshots.maven.codehaus.org/maven2</url>
      <layout>default</layout>
    </repository>
  </repositories>
  • release和snapshot分别对应了两种包类型管理策略,可以分别控制开启或停用
  • checksumPolicy即对sha1文件进行校验失败后的处理策略
  • updatePolicy即根据lastUpdated文件进行更新的策略,支持每天或指定分钟间隔进行依赖包的更新

POM文件的继承

<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>my-parent</artifactId>
  <version>2.0</version>
  <packaging>pom</packaging>


  <modules>
    <module>my-project</module>
    <module>another-project</module>
    <module>third-project/pom-example.xml</module>
  </modules>
</project>
<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
                      https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>


  <groupId>com.eastmoney.dclogs</groupId>
  <artifactId>my-project</artifactId>

  <parent>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>my-parent</artifactId>
    <version>2.0</version>
    <relativePath>../my-parent</relativePath>
  </parent>
</project>
  • packaging为pom,表示这个文件为父节点;parent用于指定父节点的Coordinate及路径
  • 应将父节点POM文件理解为一个与jar包同等对象,只是这个对象仅用于描述项目信息;Maven项目本身有一个内置POM对象,包含一些默认值,具体可参考The Super POM
  • 使用modules可以让Maven自行管理各modules之间的依赖关系;modules是用于管理模块,parent是用于管理继承,二者之间没有必然的联系

参考资源

常见Q&A

我该使用Repository还是distributionManager/Repository?

需要下载依赖包时,指定Maven仓库地址,使用Repository;需要上传公共库时,指定Maven仓库地址,使用distributionManager/Repository


我的项目中指定了依赖包如下,在编译时查询该依赖包的顺序是怎么样的?

    <dependency>
      <groupId>com.mycompany</groupId>
      <artifactId>myapp</artifactId>
      <version>1.0</version>
    </dependency>

本地repository => 项目repository => Maven-Setting.xml的repository


暂时无法使用仓库进行下载时,如何手动添加我的依赖包?

  • a. 手动添加目录及POM文件
  • b. 使用dependency的scope=system + systemPath
  • c. 使用如下Maven命令进行手动安装
mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar

我的项目依赖包含A与B,依赖包A与B又依赖了logback日志模块,但是版本冲突导致编译失败,如何解决?

使用exclusions节点进行排除


dependency与dependencyManagement的区别和使用场景?

dependency用于管理当前项目依赖包且会被后代POM文件直接继承;dependencyManagement是用于管理子module的依赖包,后代POM文件使用时必须至少指定对应groupId与artifactId

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • Maven 笔记 https://www.yiibai.com/maven/enable-proxy-settin...
    点点渔火阅读 884评论 0 3
  • 第1章 Maven 介绍 什么是 Maven 什么是 Maven Maven 的正确发音是[ˈmevən],而不是...
    强某某阅读 2,362评论 0 25
  • maven常用命令介绍 这里主要是在eclipse中使用maven,因此只使用到了一部分命令,整理下来方便以后查阅...
    菜凯阅读 1,060评论 0 2
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一个开源项目。它是用纯java开发的。是一...
    Bcome阅读 2,763评论 0 7
  • 01.拥有自己的原则 不管你是名人或是普通人每个人都有自己的行事原则,而很多人并不知道,最好经常反思自己的原则,这...
    唯其时物阅读 212评论 0 0