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文件基础配置


  4.0.0
 
  org.codehaus.mojo
  my-project
  1.0

  • model 4.0.0是目前Maven2&3唯一支持的解析版本,可以视其为固定节点。

POM文件之dependencies


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

POM文件之properties

  
    1.7
    1.7
    UTF-8
    UTF-8
  
  • 属性实际是一种占位符;使用properties节点定义,使用${property}进行占位替换
  • Maven内置了一些默认属性可供直接使用,如{project.version}、${java.home}

POM文件之repositories

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

POM文件的继承


  4.0.0
 
  org.codehaus.mojo
  my-parent
  2.0
  pom


  
    my-project
    another-project
    third-project/pom-example.xml
  


  4.0.0


  com.eastmoney.dclogs
  my-project

  
    org.codehaus.mojo
    my-parent
    2.0
    ../my-parent
  

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

参考资源

  • pom文件cookbook
  • pom文件详解

常见Q&A

我该使用Repository还是distributionManager/Repository?

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


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

    
      com.mycompany
      myapp
      1.0
    

本地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

你可能感兴趣的:(Maven之POM文件)