Maven是一个基于JAVA的工具,能够帮助项目实现环境配置和构建等操作。它能够帮助项目实现jar包的配置
,也能帮助项目进行编译、打包、输出报告和文档、自动化,他还有自带的模版系统能够帮助项目快速搭建,只不过一般情况下IDE可以帮助我们实现其中的一部分操作,日常使用Maven时只用部分功能。
仓库系统
Maven的仓库分为三类:
- 本地仓库
- 中央仓库
- 远程仓库
一般的,项目第一次运行的时候在POM文件中配置的jar包等资源会从中央仓库被下载到本地的某一个文件夹中。这个本地的文件夹就称为本地仓库。以后再次运行项目的时候会从本地仓库中直接读取资源(快照情况除外)。如果在本地和中央仓库中都没有需要的jar包,maven会报错。此时,我们可以在POM文件中进行配置,写入此jar包的远程链接,使得maven根据指定的链接下载此资源。
<repositories>
<repository>
<id>companyname.lib1</id>
<url>http://download.companyname.org/maven2/lib1</url>
</repository>
<repository>
<id>companyname.lib2</id>
<url>http://download.companyname.org/maven2/lib2</url>
</repository>
</repositories>
生命周期
maven有一套自带的生命周期体系,一般在使用maven的时候,我们不使用命令行mvn命令,所以了解生命周期的人并不多。maven的生命周期包括从‘清理上次编译信息’到‘生成报告’一次运行项目的全过程。而具体的分为三个部分:
- clean生命周期
- default生命周期
- site生命周期
这三个生命周期分别负责:清理之前项目中target文件夹下生成的编译结果、编译优化等部署项目等操作、发布项目生成文档。
阶段 | 功能 |
---|---|
预清洁(pre-clean) | 执行实际项目清理之前所需的流程 |
清洁(clean) | 删除以前构建生成的所有文件 |
后清洁(post-clean) | 执行完成项目清理所需的流程 |
阶段 | 功能 |
---|---|
验证(validate) | 验证项目是正确的,所有必要的信息可用。 |
初始化(initialize) | 初始化构建状态,例如设置属性或创建目录。 |
产生来源(generate-sources) | 生成包含在编译中的任何源代码。 |
流程源(process-sources) | 处理源代码,例如过滤任何值。 |
生成资源(generate-resources) | 生成包含在包中的资源。 |
流程资源(process-resources) | 将资源复制并处理到目标目录中,准备打包。 |
编译(compile) | 编译项目的源代码。 |
工艺类(process-classes) | 从编译后处理生成的文件,例如对Java类进行字节码增强。 |
生成测试来源(generate-test-sources) | 生成包含在编译中的任何测试源代码。 |
流程测试来源(process-test-sources) | 处理测试源代码,例如过滤任何值。 |
生成测试资源(generate-test-resources) | 创建测试资源。 |
流程测试资源(process-test-resources) | 将资源复制并处理到测试目标目录中。 |
测试编译(test-compile) | 将测试源代码编译到测试目标目录中 |
流程检验类(process-test-classes) | 从测试编译中处理生成的文件,例如对Java类进行字节码增强。对于Maven 2.0.5及以上版本。 |
测试(test) | 使用合适的单元测试框架运行测试。这些测试不应该要求代码被打包或部署。 |
制备包(prepare-package) | 在实际包装之前,执行必要的准备包装的操作。这通常会导致打包的处理版本的包。(Maven 2.1及以上) |
打包(package) | 采取编译的代码,并以其可分发的格式(如JAR)进行打包。 |
预集成测试(pre-integration-test) | 在执行集成测试之前执行所需的操作。这可能涉及诸如设置所需环境等。 |
集成测试(integration-test) | 如果需要,可以将该包过程并部署到可以运行集成测试的环境中。 |
整合后的测试(post-integration-test) | 执行集成测试后执行所需的操作。这可能包括清理环境。 |
校验(verify) | 运行任何检查以验证包装是否有效并符合质量标准。 |
安装(install) | 将软件包安装到本地存储库中,以作为本地其他项目的依赖关系。 |
部署(deploy) | 在集成或发布环境中完成,将最终软件包复制到远程存储库,以与其他开发人员和项目共享。 |
阶段 | 功能 |
---|---|
预网站(pre-site) | 在实际的项目现场生成之前执行所需的进程 |
网站(site) | 生成项目的站点文档 |
后网站(post-site) | 执行完成站点生成所需的进程,并准备站点部署 |
网站部署(site-deploy) | 将生成的站点文档部署到指定的Web服务器 |
mvn install
//在install之前的所有default的步骤都将被执行,
//install命令会将生成的软件包安装到本地存储库中,作为本地其他项目的依赖关系,
//在多服务中这种操作是经常被执行的。
插件
maven实际上是由一些插件组合而成的工具集合,我们通过这样的命令可以使用不同的插件工具:
mvn plugin-name:goal-name
mvn dependency:tree
推荐一个很好用的插件命令dependency:tree
,通过这个命令可以快速查看各种jar的依赖。
配置文件
通过设置profiles配置maven当前的属性,在resource文件夹下增加类似env.properties的文件,并如下配置maven的pom文件,通过使用命令mvn -Ptest
来激活此配置文件。这种方法可以让项目快速在生产环境,测试环境中切换。
<profiles>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="src/main/resources/env.test.propertiestofile
="${project.build.outputDirectory}/env.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
无论如何,一个完整的项目都需要groupId、artifactId、version三个属性,这三个值形成了一个项目的完全限定名(在仓库中的工程标识),如上的POM中,这个项目的完全限定名是:com.mycompany.app:my-app:1.0。
project
这是所有Maven pom.xml文件中的顶级元素。
modelVersion
此元素指示此POM正在使用的对象模型的版本。模型本身的版本很少变化,通常我们使用4.0.0即可,但是如果Maven开发人员认为有必要更改模型,则为了确保使用的稳定性是强制性的。
groupId
此元素指示创建项目的组织或组的唯一标识符。groupId是项目的关键标识符之一,通常基于您组织的完全限定域名。例如,org.apache.maven.plugins是所有Maven插件的指定groupId。
artifactId
此元素指示此项目正在生成的主要工件的唯一基本名称。项目的主要工件通常是JAR文件。诸如源码包之类的辅助工件也使用artifactId作为其最终名称的一部分。由Maven生成的典型工件将具有 - 。(例如myapp-1.0.jar)的形式。
packaging
此元素指示此工件要使用的包类型(例如JAR,WAR,EAR等)。这不仅意味着如果生成的工件是JAR,WAR或EAR,但也可以指示在构建过程中使用的特定生命周期。(生命周期是我们将在指南中进一步处理的主题,现在,请记住,指定的项目包装可以在定制构建生命周期中发挥作用。)包装元素的默认值为JAR所以你不必为大多数项目指定。
version
此元素指示项目生成的工件的版本。Maven可以帮助您进行版本管理,您将经常在一个版本中看到SNAPSHOT指示符,这表明项目处于开发状态。
dependencies
在该元素内部可以使用多个dependency元素表示该项目依赖的包。
dependency
表示项目中需要使用到的文件信息,通常可以有多个这样的dependency并列写出。
name
此元素指示用于项目的显示名称。这通常用在Maven生成的文档中。
url
此元素指示可以找到项目的站点。这通常用在Maven生成的文档中。
description
此元素提供了项目的基本描述。这通常用在Maven生成的文档中。
快照
有的时候我们使用一个用maven引入的包,但是这个包的服务在开发中,可能本项目中两次编译时引入包发生了变化。但是根据我们的中央库/本地库理论,我们下载到本地的库是不会再改变了,这样多个服务之间的灵活性会很差。
这时引入快照的概念,在版本号上增加SNAPSHOT来表示引入的是那个包的一个快照。这样在pom文件每次编译前检查的时候会把所有的SNAPSHOT重新拉下来最新版。
<groupId>data-service</groupId>
<artifactId>data-service</artifactId>
<version>1.0-SNAPSHOT</version>
自动化配置
在多服务开发中使用maven会遇到一个问题,如果ABC三个服务,A服务要依赖于BC两个服务,但是BC两个服务的开发速度很快,版本更新很频繁,那么A中的pom要不断的修改版本号以得到最新的BC版本。
或许你会说可以使用快照,但是快照只会在构建项目的时候让A重新拉取BC服务的版本,在A服务处于生产环境中时,我们不想每次其他依赖的服务更新版本就要重新部署一次A服务,这个时候有两个方法解决这个问题:
- 在A的配置文件中设置更新,每当他依赖的包发生变化,让A服务自动更新其他服务的最新版本
- 使用CI(持续集成服务器),这种持续集成服务会帮助我们在发布时候自动做好上述功能,一般情况下,我们采用这种方法,而不是第一种。