Maven
- 项目管理工具,可以对 Java 项目进行构建、依赖管理
安装
- 配置环境变量:JAVA_HOME、MAVEN_HOME
- 将 %JAVA_HOME%\bin、%MAVEN_HOME%\bin 路径添加到操作系统的 PATH 环境变量中
设置 settings. xml
通过 ~/.m2/ 目录下( ~ 表示用户目录)的 settings.xml 文件进行设置
:用于设置 Maven 的本地资源库的路径,如 E:\repository
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>central-repository</id>
<name>Central Repository</name>
<url>http://central.maven.org/maven2/</url>
<mirrorOf>central</mirrorOf>
</mirror>
pom.xm 文件
- pom.xm 文件被称为项目对象模型(Project Object Model)描述文件
:指定继承的父模块的坐标,子标签 、 、 、 (父 pom 的相对路径,设定一个空值将始终从仓库中获取,不从本地路径获取) 、 、 、 定义了该项目的唯一标识,这个唯一标识被称为 Maven 坐标 、 是 pom.xml 提供的描述性元素 :定义被聚合的模块 :自定义 Maven 属性,如 <java.version>1.8</java.version>
定义后, Maven 运行时会将 POM 中的所有的${java.version}
替换成实际值 1.8:定义依赖管理
说明:<dependencyManagement> 里只是声明版本,并不实现引入,因此子项目需要显式的声明依赖,version 和 scope 都读取自父 pom;而 <dependencies> 所有声明在主 pom 的 <dependencies> 里的依赖都会自动引入,并默认被所有的子项目继承
:定义依赖关系 :依赖管理 :指定依赖库所属的组织 ID :指定依赖库的项目名 :指定依赖库的版本号 :指定依赖库起作用的范围,内容可以为: - compile:编译依赖范围,对于编译、测试,运行三种 classpath 都有效(无指定时默认使用该依赖范围)
- test:测试依赖范围,只对于测试 classpath 有效
- provided:已提供依赖范围,对于编译和测试 classpath 有效,但在运行时无效
- runtime:运行时依赖范围,对于测试和运行 classpath 有效,但在编译主代码时无效
- system:系统依赖范围,对于编译和测试 classpath 有效,但在运行时无效,必须通过 systemPath 元素显式地指定依赖文件的路径
- import:导入依赖范围,继承父 POM 文件中用 dependencyManagement 配置的依赖
:指定该依赖库是否为可选的,可选依赖不被传递 :JDK 版本号 :用于排除依赖,子标签
:定义构建信息 :定义插件管理 ,子标签 、 、 、
Maven 的主要约定
源代码应该位于 ${basedir}/src/main/java 路径下
资源文件应该位于 ${basedir}/src/main/resources 路径下
- 测试代码应该位于 ${basedir}/src/test 路径下
- 编译生成的 class 文件应该位于 ${basedir}/target/classes 路径下
- 项目打包后会产生一个 jar文件,并将生成的 JAR 包放在 ${basedir}/target 路径下
图 1 Maven项目的文件结构
Maven 默认的生命周期(lifecycle)的核心阶段
- compile:编译项目
- test:单元测试
- package:项目打包
- install:安装到本地仓库
- deploy:部署到远程仓库
Maven 的坐标(coordinate)
- groupld:该项目的开发者的域名
- artifactld:指定项目名
- version:指定项目的版本
- packaging:指定项目打包的类型,可用值:jar(默认)、war、pom
Maven 的仓库(repository)
- 本地仓库
- 远程仓库(私服、其它公共库、中央仓库 central)
Maven 依赖调解
Maven 依赖调解(Dependency Mediation)的原则:
- 第一原则:路径最近者优先
- 第二原则:第一声明者优先。在依赖路径长度相等的前提下,在 POM 中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜
Maven 常用命令
- mvn 命令的基本用法:
mvn [options] [<goal(s)>] [<phase(s)>]
,options 表示可用的选项,goal 指插件目标,phase 指生命周期阶段 mvn –v
// 显示版本信息mvn compile
// 编译mvn clean
// 清空生成的文件mvn clean compile
mvn clean test
// 编译并测试mvn clean package -Dmaven.test.skip=true
// 打包mvn clean site
// 生成项目相关信息的网站mvn install
// 在本地 Repository 中安装 jarmvn install -Dmaven.test.skip=true -Pdev
// 跳过测试,激活 id 为 dev 的 profilemvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.2.0 -Dpackaging=jar -Dfile=E:\ojdbc14-10.2.0.2.0.jar
// 安装 jar 包到本地仓库mvn dependency:list
// 査看当前项目的已解析依赖mvn dependency:tree
// 査看当前项目的依赖树mvn dependency:analyze
// 分析当前项目的依赖,分析结果包含Used undeclared dependencies found
(项目中使用到但是没有显式声明的依赖)和Unused declared dependencies found
(项目中未使用但显式声明的依赖)mvn idea:idea
// Maven 项目生成 idea 项目文件mvn idea:clean
// 清除 idea 的项目工程文件mvn eclipse:eclipse
// Maven 项目生成 eclipse 项目文件
Maven 属性
- 内置属性:
${basedir}
表示项目根目录(即包含 pom.xml 文件的目录);${version}
表示项目版本 - POM 属性:引用 POM 文件中对应元素的值,如
${project.groupId}
、${project.artifactId}
、${project.version}
分别对应项目的 groupId、artifactId、version - 自定义属性:在 POM 的
元素下自定义 Maven 属性 - Setting 属性:使用以 settings. 开头的属性引用 settings.xml 文件中 XML 元素的值,如
${settings.localRepository}
指向用户本地仓库的地址 - Java 系统属性:引用 Java 系统属性,如
${user.home}
- 环境变量属性:使用以 env. 开头的属性引用环境变量,如
${env.JAVA_HOME}
资源过滤
- 针对不同环境的 profile
<profiles>
<profile>
<id>dev</id>
<!-- 定义 Maven 属性 -->
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
</profile>
</profiles>
<build>
<!-- 主资源文件由 maven-resources-plugin 处理 -->
<resources>
<!-- 定义资源 -->
<resource>
<!-- 指定资源所在目录 -->
<directory>src/main/resources</directory>
<!-- 指定资源文件:所有 properties 文件 -->
<includes>
<include>**/*.properties</include>
</includes>
<!-- 对资源文件开启过滤,解析资源文件中的 Maven 属性 -->
<filtering>true</filtering>
</resource>
<!-- 定义资源二 -->
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
</build>
在资源文件中使用 Maven 属性
${activateProperties}
如果项目的 pom 已经继承 spring-boot-starter-parent,则占位符${..}
被替换为@..@
,即使用方式为@activateProperties@
(可通过 maven-resources-plugin 插件的属性自定义) 激活 profile
- 命令行激活,多个 id 之间以逗号分隔
mvn install -Pdev
- settings 文件显式激活,配置 settings xml 文件的
元素 - 系统属性激活:当某系统属性存在的时候,自动激活 profile,定义
中的 属性 - 操作系统环境激活:自动根据操作系统环境激活,定义
中的 属性 - 文件存在与否激活:根据项目中某个文件存在与否来决定是否激活,定义
中的 属性 - 默认激活,定义
中的 属性
- 命令行激活,多个 id 之间以逗号分隔
Maven 多模块
maven 多个子模块项目管理
主项目 parent 包
- 指定整个应用的 dependencyManagement
- 定义项目的发布的仓库地址 distributionManagement
- 所有第三方依赖的版本号全部定义在 properties 下
- 所有内部模块依赖版本号统一使用
${project.version}
- 指定所有的子模块 modules
项目子模块 pom.xml
- 明确定义 parent 模块的 groupId、artifactId、version
- 不要定义子模块的 version(同 parent 保持一致)
- 子模块无需定义 groupId
- 子模块所有的依赖包版本全部集成 parent 模块,即:子模块不得定义依赖包版本号
- 子模块需定义是否需要 deploy 到私服
<maven.deploy.skip>true</maven.deploy.skip>
- 对于需要 depoly 的子模块(对外发布的,比如 dubbo 提供的 api 包)不应该依赖重量级 jar 包(比如 spring, mybatis 等)
子模块 packaging 为 pom
- 明确定义 parent 模块的 groupId、artifactId、version
- 指定所有的子模块 modules
- 无需定义 groupId
多个子模块项目版本号修改
- 在项目顶层 pom 中添加 version 插件 org.codehaus.mojo:versions-maven-plugin
- 在项目根目录下执行以下命令修改版本号
mvn versions:set -DnewVersion=1.1.0
Gradle
- 基于 Apache Ant 和 Apache Maven 概念的项目自动化构建开源工具
- 使用一种基于 Groovy 的特定领域语言(DSL)来声明项目设置
安装
- 配置环境变量:JAVA_HOME、GRADLE_HOME、GRADLE_USER_HOME
- 将 %JAVA_HOME%\bin、%GRADLE_HOME%\bin 路径添加到操作系统的 PATH 环境变量中
- 配置远程仓库:在 GRADLE_USER_HOME 目录下添加 init.gradle 文件
allprojects {
repositories {
mavenLocal()
// maven { url 'file:///E:/repository/'}
maven { name "AliyunNexus"; url "https://maven.aliyun.com/repository/public" }
mavenCentral()
}
buildscript {
repositories {
maven { name "AliyunNexus"; url 'https://maven.aliyun.com/repository/public' }
maven { name "M2"; url 'https://plugins.gradle.org/m2' }
}
}
task showRepositories {
doLast {
repositories.each {
println "repository: ${it.name} ('${it.url}')"
}
}
}
}