前言
maven做为现在最流行的依赖管理及构建工具之一,是做为Java开发者的必修课之一。特此,笔者阅读完《maven官方文档》总结了一下。
配置文件
maven配置文件主要有以下2部分。
- pom.xml
- 项目中的pom.xml
- pom.xml文件默认文档 Super POM
- settings.xml
- 系统级别:${maven.home}/conf/settings.xml
- 用户级别:%USER_HOME%/.m2/settings.xml
仓库规则
对于maven来说,仓库只分为2类,本地仓库和远程仓库。
maven的规则:
- 优先在本地仓库进行寻找
- 从远程仓库进行获取
- 如果多个远程仓库时,一个远程找不到,会去其它的远程仓库找
- 如果远程仓库配置了镜象服务器,则会去其镜象上找
- 都找不到都报错
仓库配置
<!-- 本地仓库 -->
<localRepository>D:/maven/maven-repository/</localRepository>
<!-- 远程仓库 -->
<!-- 配置多个远程仓库时,super pom 默认会有一个ID是central的官方远程仓库 -->
<repositories>
<repository>
<id>nexus</id>
<name>nexus私服</name>
<url>http://127.0.0.1:8081/repository/maven-public/</url>
<!-- 下载快照版本稳定版 -->
<snapshots><enabled>true</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
<repository>
<id>aliyun</id>
<name>阿里云</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<!-- 仅下载稳定版 -->
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
</repositories>
<!-- 镜像仓库,相当于远程仓库的CND -->
<mirrors>
<mirror>
<id>aliyun</id>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<!-- 对应哪个仓库的镜像,对应repository的ID,还支持特定的表达式 -->
<!-- 配置多个镜像时,只会寻找最先匹配的镜像,不会遍历所有镜像 -->
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
上传配置
<!-- 私服仓库会有一个账户密码的认证 -->
<servers>
<server>
<id>my-proj</id>
<username>repo-my</username>
<password>123123</password>
</server>
</servers>
<distributionManagement>
<repository>
<id>proj-my</id>
<name>123</name>
<url>http://xxx</url>
</repository>
<!-- snapshotRepository表示是快照版本要发布的仓库地址 -->
<snapshotRepository>
<id>proj-my</id>
<name>123</name>
<url>http://xxx</url>
</snapshotRepository>
</distributionManagement>
总结
- 如果没有nexus私服,可以使用aliyun镜像来加速默认的官方远程仓库
- 如果有nexus私服,可以同时使用aliyun镜像和私服远程仓库,aliyun镜像用于加速官方仓库,私服用于加载第三方jar包和自己deploy的jar包(推荐)
- 如果私服nexus联网,直接新建repository,设置远程代理到aliyun
多环境配置
根据不同的环境,使用不同的配置。maven为我们提供了Profiles
<profiles>
<profile>
<!-- test 环境对应的 properties,repositories 配置 -->
<id>test</id>
<properties></properties>
<repositories></repositories>
<pluginRepository></pluginRepository>
<!-- test 对应的触发机制 -->
<activation>
<!-- 是否默认 -->
<activeByDefault>false</activeByDefault>
<!-- jdk版本激活 -->
<jdk>1.5</jdk>
<!-- 系统版本激活 -->
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
<!-- 环境变量激活 -->
<property>
<name>mavenVersion</name>
<value>2.0.3</value>
</property>
<!-- 文件规则激活 -->
<file>
<exists>${basedir}/file2.properties</exists>
<missing>${basedir}/file1.properties</missing>
</file>
</activation>
</profile>
</profiles>
<!-- 强制激活 env-test-->
<activeProfiles>
<activeProfile>env-test</activeProfile>
</activeProfiles>
pom文件
另外再基于 pom.xml,主要分为三部份:
- Basics 项目基础信息
- Build 构建方式
- More Project Information 关于项目介绍信息(略)
- Environment Settings 环境信息
Basics
<project>
<!-- groupId:artifactId:version 确立包的唯一性 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<!-- 打包方式, 根据打包方式的不同,会选择不同默认build流程 -->
<!-- 可选值: -->
<!-- pom:只作项目的子模块的整合 -->
<!-- jar:以jar的方式打包(默认) -->
<!-- maven-plugin:maven插件 -->
<!-- 其它:ejb, war, ear, rar -->
<packaging>...</packaging>
<!-- 声明父亲配置文件,配合packaging:pom使用 -->
<!-- 相当于复制父亲配置文件中的所有配置项进来 -->
<!-- super pom配置文件是系统默认声明的 -->
<parent>...</parent>
<!-- 子项目声明,只出现packaging:pom 项目中,和 parent 相对应-->
<!-- 负责告之父亲项目,其子项目路径,方便统一编译 -->
<modules>...</modules>
<!-- maven 变量声明,可作用maven各标签内 -->
<properties>...</properties>
<!-- 依赖关系集合 -->
<dependencies>
<!-- groupId:artifactId:version 确立依赖的唯一性 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- 包唯一性上面再增加环境版本区分,例:json-lib-2.2.2-jdk15.jar -->
<classifier>jdk15</classifier>
<!-- 以什么方式引入依赖 -->
<!-- 可选值: -->
<!-- jar:引入此包,包括其依赖 (默认) -->
<!-- pom:只引入其依赖 -->
<!-- 其它:不详 -->
<type>jar</type>
<!-- 包的作用域:见下图,结合build生命周期使用 -->
<scope>test</scope>
<!-- 结合scope为 system时使用,指定包路径 -->
<systemPath></systemPath>
<!-- 是否可选依赖,默认值根据scope决定 -->
<!-- false: 引入主包时,自动引入此依赖包 -->
<!-- true: 引入主包时,不会引入此依赖包 -->
<optional>true</optional>
<!-- 根据一定规则可排除自动依赖包 -->
<exclusions></exclusions>
</dependencies>
<!-- 依赖关系管理,相当于对dependencies配置抽象 -->
<!-- 一般作用于packaging:pom 的项目-->
<!-- 统一管理所有子项目的依赖配置,防止包冲突 -->
<dependencyManagement>...</dependencyManagement>
</project>
针对scope取值整理如下:
scope取值 | 有效范围(compile, runtime, test) | optional默认值 |
---|---|---|
compile | compile, runtime, test | false |
provided | compile, test | true |
runtime | runtime, test | false |
test | test | true |
system | compile, test | false |
system: 在编译、测试时有效,但是在运行时无效。和provided的区别是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径
Build
<project>
<build>
<!-- 默认的执行周期 -->
<defaultGoal>install</defaultGoal>
<!-- 编译,运行的工作目录 -->
<directory>${basedir}/target</directory>
<!-- 打成包后的文件名 -->
<finalName>${artifactId}-${version}</finalName>
<!-- 使用properties 所下面文件中的值全部替换了 -->
<filters>
<filter>filters/filter1.properties</filter>
</filters>
<!-- 根据一定规则导入资源(配置)文件到工作目录中 -->
<resources>
<!-- 目标路径:相对工作目录 -->
<targetPath>META-INF/plexus</targetPath>
<!-- 是否开始变量替换,资源文件中的${} -->
<filtering>false</filtering>
<!-- 资源文件的源路径 -->
<directory>${basedir}/src/main/plexus</directory>
<!-- 黑名单,配置规则的文件将不会被复制 -->
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
<!-- 白名单,黑名单中符合配置规则的文件将会被复制 -->
<includes>
<include>configuration.xml</include>
</includes>
</resources>
<!-- 和 resources 相似,只是 资源(配置)文件 只作用在测试 -->
<testResources> </testResources>
<!-- 源文件路径 -->
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<!-- 源脚本文件路径 -->
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<!-- 源测试文件路径 -->
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<!-- class文件输出路径 -->
<outputDirectory>${basedir}/target/classes</outputDirectory>
<!-- 测试class文件输出路径 -->
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
<!-- maven 插件 -->
<plugins>
<plugin>
<!-- groupId:artifactId:version 插件的唯一性 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<!-- 插件jar的相关依赖 -->
<dependencies>...</dependencies>
<!-- 是否提前下载扩展相关的文件,如果为false,则在使用到的时候进行下载 -->
<extensions>false</extensions>
<!-- 插件jar的相关的全局配置 -->
<configuration>...</configuration>
<!-- 插件jar的是否可传递的全局配置-->
<inherited>true</inherited>
<!-- 一个插件jar包括多个部分称之为“插件扩展”-->
<executions>
<execution>
<!-- 名字为echodir的插件扩展 -->
<id>echodir</id>
<!-- echodir的插件所包含的命令集合 -->
<goals>
<!-- 相当于运行 echodir:run -->
<goal>run</goal>
</goals>
<!-- 绑定的maven的构建周期,自动触发goals中的命令 -->
<phase>verify</phase>
<!-- 是否可被子项目继承, 相当于在子项目 verify 是否会自动执行goals -->
<inherited>false</inherited>
<!-- echodir 插件的相关配置 -->
<configuration>... </configuration>
</executions>
</plugin>
</plugins>
<!-- 和 dependencyManagement 功能类似,一般作用于pom -->
<pluginManagement>...</pluginManagement>
<!-- 把插件中的所有扩展引入 -->
<extensions>...</extensions>
</build>
<!-- 关于项目报告网站生成的一些配置信息 -->
<reporting>...</reporting>
</project>
More Project Information
主要介绍项目网址,开发者,组织及一些其它信息
<project>
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
</project>
Environment
作用在于覆盖setting.xml中的一些配置信息。
<project>
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
构建周期
《maven项目的构建周期》可以说是maven的核心部分。Maven拥有三套相互独立的生命周期。分别为clean、default和site。
- clean:清理
Phase | Description |
---|---|
pre-clean | 执行一些清理前需要完成的工作 |
clean | 清理上一次构建生成的文件 |
post-clean | 执行一些清理后需要完成的工作 |
- Default: 构建
Phase | Description |
---|---|
validate | 验证项目信息 |
initialize | 初始化构建状态,设置properties 或者 创建target目录. |
generate-sources process-sources | 源代码处理,比如过滤 |
generate-resources process-sources | 处理项目主资源文件。对src/main/resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中 |
compile | 编译项目的主代码,编译src/main/java目录下的Java文件至项目输出的主classpath目录中 |
process-classes | 对编译后生成的文件进行后处理,例如对Java类进行字节码增强 |
generate-test-sources process-test-sources | 处理项目测试源代码src/test/java |
generate-test-resources process-test-resources | 处理项目测试资源文件src/test/resources |
test-compile | 编译项目的测试代码。src/test/java |
process-test-classes | 对编译后生成的测试文件进行后处理,例如对Java类进行字节码增强 |
test | 使用单元测试框架运行测试 |
prepare-package package | 打包编译好的代码,及依赖scope(compile,rumtime) |
pre-integration-test integration-test post-integration-test | 处理该程序包并将其部署到可以运行集成测试的环境中 |
verify | 对集成测试的结果进行任何检查,以确保符合质量标准 |
install | 将包提交到Maven本地仓库 |
deploy | 将包提交到远程仓库 |
- site : 文档
Phase | Description |
---|---|
pre-site | 执行一些文档生成前需要完成的工作 |
site | 生成项目站点文档 |
post-site | 执行一些文档生成后需要完成的工作 |
site-deploy | 将生成的项目站点发布到服务器上 |
default的周期这么多,全部都有用?
default的周期执行原理是什么?
maven根据的值不同,给各周期配置不同的默认插件,来实现的。以 jar 为默认为例:
Phase | plugin:goal |
---|---|
process-resources | resources:resources |
compile | compiler:compile |
process-test-resources | resources:testResources |
test-compile | compiler:testCompile |
test | surefire:test |
package | jar:jar |
install | install:install |
deploy | deploy:deploy |
如果要用的别的周期,可以build中配置plugin
所以,我们的maven默认支持 clean compile test package install deploy等命令,来触发其周期
高级进阶
- maven插件开发
- maven模板开发