b1cat`s

Maven基础

Word count: 1.8kReading time: 8 min
2020/02/23

Maven基础

Maven就是是专门为Java项目打造的管理和构建工具,它的主要功能有

  • 提供了一套标准化的项目结构;
  • 提供了一套标准化的构建流程(编译,测试,打包,发布……);
  • 提供了一套依赖管理机制

结构

image-20200223092351225

  • 根项目名称:a-maven-project

  • 项目描述pom.xml

  • 存放源码src/main/java

  • 存放资源src/main/resources

  • 存放测试源码src/test/java

  • 存放测试资源src/test/resources

  • 编译、打包生成的文件target

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>hello</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
...
</properties>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
  • groupId 类似Java包名,通常是公司或组织名
  • artifactId 类似于Java的类名
  • version

引入第三方库,也是通过这三个变量确定

  • <dependency>声明依赖,Maven会自动下载依赖包并放在classpath

依赖管理

Maven第一个作用就是解决依赖管理,如我们需要abc包,而abc依赖xyz包,Maven会自动导入依赖包。

Maven定义了几种依赖关系

  • compile 编译时需要用的该jar包(默认), 如commons-logging
  • test 编译Test需要用到,如junit
  • runtime 编译时不需要,运行时需要 如mysql
  • provided 编译时需要,但由JDK或服务器提供 如servlet-api
1
2
3
4
5
6
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>

Maven维护一个中央仓库(repo1.maven.org),所有第三方库将自身的jar以及相关信息上产至中央仓库。

  • 一旦jar包被下载过,会自动缓存至用户根目录.m2
  • 唯一ID,通过groupId,artifactId,version确定jar包,maven对包使用PGP签名。
  • SNAPSHOT-开头的版本号为开发版本, 每次都会重复下载

国内源

在.m2目录下settings.xml设置

1
2
3
4
5
6
7
8
9
10
<settings>
<mirrors>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirror>
</mirrors>
</settings>

如何搜索包

https://search.maven.org/

构建流程

Maven还有一套标准化的构建流程,实现自动化编译,打包,发布等

Lifecycle(生命周期)和Phase(阶段)

Maven的生命周期由一系列阶段构成,以内置的生命周期default为例,包含以下阶段:

image-20200223102902490

  • 运行mvn package 执行default生命周期,执行到package阶段
  • 运行mvn compile执行default生命周期,执行到compile阶段
  • mvn 阶段 ,执行到设定阶段

另一个生命周期clean,包含以下阶段

- pre-clean
- clean
- Post-cleam

多阶段执行mvn clean package, 先执行clean生命周期的clean阶段,然后执行default的package阶段

Goal(执行阶段的具体方法)

执行一个phase会触发一个或多个Goal,明明形式abc:xyz

image-20200223103913656

少数情况需要执行运行goal,例如启动tomcat服务器

mvn tomcat:run

使用插件

实际上,执行每个phase,都是通过某个插件(plugin)来执行,比如mvn compile Maven本身并不知道如何执行,它只是负责找到对应的compiler插件,然后执行默认的compiler:compile这个goal来完成编译

image-20200223104351674

自定义插件

使用自定义插件的时候,需要声明。例如,使用maven-shade-plugin可以创建一个可执行的jar,要使用这个插件,需要在pom.xml中声明它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

自定义插件往往需要一些配置,例如,maven-shade-plugin需要指定Java程序的入口,它的配置是:

1
2
3
4
5
6
7
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.itranswarp.learnjava.Main</mainClass>
</transformer>
</transformers>
</configuration

Maven自带的标准插件例如compiler是无需声明的,只有引入其它的插件才需要声明。

下面列举了一些常用的插件:

  • maven-shade-plugin:打包所有依赖包并生成可执行jar;
  • cobertura-maven-plugin:生成单元测试覆盖率报告;
  • findbugs-maven-plugin:对Java源码进行静态分析以找出潜在问题。

模块管理

Maven支持模块化管理,可以把一个大项目拆成几个模块:

image-20200223105353816

  • 可以通过继承在parent的pom.xml统一定义重复配置;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<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.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>

<name>parent</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<java.version>11</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.28</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

模块A继承parent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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>

<parent>
<groupId>com.itranswarp.learnjava</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

<artifactId>parent</artifactId>
<packaging>jar</packaging>
<name>module-a</name>
</project>
  • Maven根据根目录的pom.xml找到包括parent在内的共4个``,一次性全部编

使用mvnw

mvnw是Maven Wrapper缩写,作用是只针对特定的项目安装特定斑斑的Maven,而不影响其他项目。

安装Maven Wrapper(官网)最简单的方式是在项目的根目录(即pom.xml所在的目录)下运行安装命令:

1
mvn -N io.takari:maven:0.7.6:wrapper //使用最新版本的Maven,0.7.6是mvnw版本

如果要指定使用的Maven版本,使用下面的安装命令指定版本,例如3.3.3

1
mvn -N io.takari:maven:0.7.6:wrapper -Dmaven=3.3.3

image-20200223110127225

发现多了mvnwmvnw.cmd.mvn目录,我们只需要把mvn命令改成mvnw就可以使用跟项目关联的Maven。

CATALOG
  1. 1. Maven基础
    1. 1.0.0.1. 依赖管理
    2. 1.0.0.2. 构建流程
      1. 1.0.0.2.1. Lifecycle(生命周期)和Phase(阶段)
      2. 1.0.0.2.2. Goal(执行阶段的具体方法)
    3. 1.0.0.3. 使用插件
    4. 1.0.0.4. 模块管理
    5. 1.0.0.5. 使用mvnw