Maven

简介

Apache Maven是一个软件项目管理的综合工具,基于项目对象模型(POM)的概念,Maven可以从一个中心资料片管理项目构建,报告和文件。

Maven提供给开发人员构建一个完整生命周期的框架。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。

在多个开发团队的环境时,Maven可以设置按照标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时拥有创建报表,检查,构建和测试自动化设置等功能。


核心元素

  • POM:

  代表项目对象模型。它是工作在Maven的基本单位。这是一个XML文件。它始终驻留在该项目基本目录。POM 包含的项目使用Maven来构建该项目和各种配置的详细信息。 POM 文件要求的三个必填字段: groupId(项目组),artifactId(项目名字),version(版本)。

  • 超级POM:

  所有的POM继承自父类(尽管明确界定)。这个基础POM被称为超级POM,并包含继承默认情况下的值。 Maven使用有效的POM(超级POM加项目配置的配置)执行有关的目标。它可以帮助开发人员指定的最低配置的详细信息在pom.xml。

  • 插件:

  Maven是一个实际执行的插件框架,每一个任务实际上是由插件完成的。

  一个插件通常提供了一组目标,可使用以下语法来执行:

mvn [plugin-name]:[goal-name]

Maven提供以下两种类型的插件:

类型 描述
构建插件 他们在生成过程中执行,并应在pom.xml中的<build>元素进行配置
报告插件 他们的网站生成期间执行的,他们应该在pom.xml中的<reporting>元素进行配置

Maven实战

  1. 创建项目
      Maven使用原型插件来创建项目。要创建一个简单的Java应用程序,我们使用maven-archetype-quickstart插件。在下面的例子中,我们将创建一个基于Maven的Java应用程序项目在C:\MVN文件夹。
      打开命令控制台,进入到C:\MVN目录并执行以下命令mvn命令。

C:\MVN>mvn archetype:generate -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

  也可以使用控制台交互的方式创建一个项目模板,使用一下命令打开交互模式(Generating project in Interactive mode):

C:\MVN>mvn archetype:generate

  然后会提示输入项目模板代号,后面会依次要求输入项目组名,项目名,版本号;


2. Maven添加依赖
  在pom.xml文件中可以添加依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- 外部依赖,依赖的jar并不是来自仓库 -->
<dependency>
<groupId>ldapjdk</groupId>
<artifactId>ldapjdk</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
</dependency>
</dependencies>

  Maven的核心特征是依赖管理,Maven提供了一个高程度的控制来管理这样的场景。我们只需要在每个项目POM定义直接依赖关系,Maven自动处理其余部分。(传递依赖发现)

  1. 常用的Maven命令
    mvn package 生成target目录,编译、测试代码,生成测试报告,生成jar/war文件
    mvn jetty:run 运行项目于jetty上
    mvn compile 编译
    mvn test 编译并测试
    mvn clean 清空生成的文件
    mvn site 生成项目相关信息的网站
    mvn eclipse:eclipse 将项目转化为Eclipse项目

  2. 构建自动化-Hudson(哈德森)(有待探索)
    可以帮助在版本管理系统中更新代码时,主动更新相关联的项目!
    提供持续集成服务,方便开发人员在提交新代码之后,对整个代码库进行自动化的构建,测试,部署等任务!并可以将报告反馈开发人员,方便修改问题代码。
    详细使用可以参见《Maven实战》第11章 使用Hudson进行持续集成


读书笔记·《Maven实战》

第3章 maven入门

  1. 编写POM,基本元素有
1
2
3
4
5
6
7
<project>
<modelVersion><!-- POM模板版本,最新稳定为‘4.0.0’ --></modelVersion>
<groupId><!--(项目组)--></groupId>
<artifactId><!--(项目名字)--></artifactId>
<version><!--(版本)--></version>
<name><!-- --></name>
</project>
  1. Maven项目中默认的主代码目录是/src/main/java,默认的测试代码目录是src/test/java

  2. Maven编译插件compiler默认只支持JAVA 1.3,需要显示指定编译器的版本
1
2
3
4
5
6
7
8
9
10
11
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${org.apache.maven.plugins.maven-compiler-plugin.version}</version>
<configuration>
<source>${jar.source}</source>
<target>${jar.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>

第5章 坐标和依赖

4.依赖
依赖范围

compile:编译依赖范围,默认。对编译、测试、运行的classpath有效;
test:测试依赖范围,仅对测试的classpath有效;
provided:已提供依赖范围,仅对编译、测试的classpath有效;
runtime:运行时依赖范围,仅对运行、测试的classpath有效;
system:系统依赖范围,自己制定本地的依赖文件路径,与provided依赖范围一致;

传递性依赖

依赖调解第一原则:路径最短者优先依赖,例:

1
2
3
4
5
有两个依赖路径:
A -> B -> Y(1.0)
A -> B -> X -> Y(2.0)

则A 传递性依赖 Y(1.0);

依赖调解第二原则:声明在前者优先依赖,例:

1
2
3
4
5
有两个依赖路径,且在A的POM文件里 B声明在X前面:
A -> B -> Y(1.0)
A -> X -> Y(1.0)

则A 传递性依赖 Y(1.0);

通过以下两种方式可以改变依赖传递性:

  • 可选依赖: 依赖将不会被传递(被动);
    声明元素
1
2
3
<dependency>
<option>true</option>
</dependency>
  • 排除依赖: 排除指定的传递性依赖(主动)
    声明元素
1
2
3
4
5
<dependency>
<exclusions>
<exclusion></exclusion>
</exclusions>
</dependency>
归类依赖

统一系列的框架包,可以声明元素来统一指定版本

1
2
3
<properties>
<{customName}></{customName}>
</propertites>
优化依赖

mvn dependency:list

mvn dependency:tree

mvn dependency:analyze

可以通过以上命令对项目的依赖进行查看;
analyze分析后的依赖中可能会出现:Used unDeclared dependencies (项目中使用到未显式声明的依赖)和 Unused declared denpendencies(项目中有声明的依赖未使用),应该特别注意!

第8章 聚合与继承

聚合

通过聚合将多个模块组合到一起,方便进行统一的管理

1
2
3
4
<packaging>POM</packaging><!-- 默认为jar,此处必须改为POM -->
<modules>
<module><!-- 子模块的相对路径 --></module>
</modules>
继承

模块之间的继承可以消除公用部分的重复代码

1
2
<!-- parent module -->
<packaging>POM</packaging><!-- 默认为jar,此处必须改为POM -->
1
2
3
4
5
6
7
8
9
10
11
<!-- children module -->
<groupId></groupId><!-- 可省略 -->
<artifactId></artifactId><!-- 可省略 -->
<version></version>
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<relativePath><!-- POM文件的相对路径 --></relativePath>
</parent>
<packaging>jar</packaging>

继承中的依赖管理
声明在父模块中的依赖管理元素,子模块可以可选的继承,即在模块中的出现相同的<dependency>元素(省略<version>)即为继承,以此来保证各个子模块的依赖版本号一致;

1
2
3
4
<!-- parent module -->
<dependencyManagement>
<dependencies></dependencies>
</dependencyManagement>

如果是子模块全部依赖父模块,可以通过下列的方式来实现:

1
2
3
4
5
6
7
8
9
10
11
<dependencyManagement>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId><!-- parent module --></artifactId>
<version></version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
反应堆

在Maven项目中,反应堆指所有模块组成的构建结构;

反应堆的构建顺序根据各模块之间的依赖继承关系而来,模块之间的依赖关系将反应堆构成一个有向非循环图(Directed Acyclic Graph,DAG),这个图不允许出现循环,否则Maven将报错!

裁剪反应堆,通过命令指定部分构建的模块,可以通过一下命令获取帮助查看裁剪命令

mvn -h

第10章 使用Maven进行测试

Maven通过 maven-surefire-plugin 插件来运行单元测试用例;

  • 跳过测试

mvn pacakge -DskipTests

or还可以通过在POM文件中配置maven-surefire-plugin插件来跳过测试

  • 动态指定测试用例

  • 包含和排除测试用例

  • 测试覆盖率报告

mvn cobertura:cobertura

  • 重用测试代码
    一部分测试代码需要重用,默认打包不会生成测试代码的jar,通过插件可以将测试类打包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

第17章 编写Maven插件

TODO

第18章 Archetype

自定义archetype

通过自定义archetype,可以方便生成我们平常所需的项目骨架。

archetype-catalog.xml
当不指定archetype的坐标时,使用命令mvn archetype:generate会产生一个archetype的列表供用户选择,该列表的内容来自于archetype-catalog.xml。
使用自定义的archetype生成项目骨架前,应该将自定义的archetype坐标写入archetype-catalog.xml里面。

archetype-catalog来源

internal:maven-archetype-plugin内置;
local:本地,~/.m2./archetype-catalog.xml(默认不存在);
remote:maven中央仓库;
file://...:用户指定本机任意位置;
http://...:用户指定网络中任意位置;

archetype-catalog.xml内容形如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<archetype-catalog xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0 http://maven.apache.org/xsd/archetype-catalog-1.0.0.xsd"
xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<archetypes>
<archetype>
<groupId>org.apache.maven.archetypes</groupId>
<artifactId>maven-archetype-quickstart</artifactId>
<version>1.1</version>
<description>quickstart</description>
</archetype>
</archetypes>
</archetype-catalog>

指定生成命令mvn archetype:generate -DarchetypeCatalog=file://时将使用的archetype-catalog.xml的位置,等号后面的内容可以替换为来源的任意一个。

archetype自定义
自定义的文件应该都放在src/main/resources/下,
——src/main/resources/
|———— maven/archetype-metadata.xml
|———— archetype-resources/ $(相当于生成项目的根目录)
|—————— pom.xml
|—————— 其他的资源文件

archetype-metadata.xml为archetype资源的描述定义文件
archetype-metadata.xml官方参考文档

Demo

单模块简单DEMO
多模块复杂DEMO


Maven
https://oabern.github.io/posts/20160803120011998/
作者
OABern
发布于
2016年8月3日
许可协议