管理工具-Maven

Maven介绍

Maven 是一个项目管理和构建自动化工具. Maven使用惯例优与配置的原则.
它要求在没有定制之前,所有的项目都有如下的结构:

目的 功能
${basedir} 存放 pom.xml和所有的子目录(工程根目录)
${basedir}/src/main/java 项目的 java源代码
${basedir}/src/main/resources 项目的资源文件,比如说 property文件
${basedir}/src/test/java 项目的测试类,比如说 JUnit代码
${basedir}/src/test/resources 测试使用的资源

说明: 编译后的classes会放在 ${basedir}/target/classes下面

Maven配置

Maven 依赖包下载

Maven官网下载Maven包: https://maven.apache.org/download.cgi

1
2
[root@localhost /local ]$ wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.5.0/binaries/apache-maven-3.5.0-bin.tar.gz
[root@localhost /local ]$ tar -zxvf apache-maven-3.5.0-bin.tar.gz

Maven 配置环境变量

/etc/profile文件末尾追加环境变量,如下:

1
2
3
4
5
6
7
8
# 设置Meven环境变量
M2_HOME=/usr/local/apache-maven-3.5.0
# 设置Java环境变量
JAVA_HOME=/usr/local/jdk1.8.0_121
JRE_HOME=/usr/local/jdk1.8.0_121/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$M2_HOME/bin:
export M2_HOME JAVA_HOME JRE_HOME CLASS_PATH PATH

使配置生效

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
[root@localhost ~]$ source /etc/profile
[root@localhost ~]$ mvn -version
Apache Maven 3.5.0 (35c39251d2af99b6624d40d801f6ff02; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/apache-maven-3.5.0
[root@localhost wuyu-module ]$ mvn -help

usage: mvn [options] [<goal(s)>] [<phase(s)>]

Options:
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
-B,--batch-mode Run in non-interactive (batch)
mode
-b,--builder <arg> The id of the build strategy to
use.
-C,--strict-checksums Fail the build if checksums don't
match
-c,--lax-checksums Warn if checksums don't match
-cpu,--check-plugin-updates Ineffective, only kept for
backward compatibility
-D,--define <arg> Define a system property
-e,--errors Produce execution error messages
-emp,--encrypt-master-password <arg> Encrypt master security password
-ep,--encrypt-password <arg> Encrypt server password
-f,--file <arg> Force the use of an alternate POM
file (or directory with pom.xml).
-fae,--fail-at-end Only fail the build afterwards;
allow all non-impacted builds to
continue
-ff,--fail-fast Stop at first failure in
reactorized builds
-fn,--fail-never NEVER fail the build, regardless
of project result
-gs,--global-settings <arg> Alternate path for the global
settings file
-gt,--global-toolchains <arg> Alternate path for the global
toolchains file
-h,--help Display help information
-l,--log-file <arg> Log file where all build output
will go.
-llr,--legacy-local-repository Use Maven 2 Legacy Local
Repository behaviour, ie no use of
_remote.repositories. Can also be
activated by using
-Dmaven.legacyLocalRepo=true
-N,--non-recursive Do not recurse into sub-projects
-npr,--no-plugin-registry Ineffective, only kept for
backward compatibility
-npu,--no-plugin-updates Ineffective, only kept for
backward compatibility
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
-o,--offline Work offline
-P,--activate-profiles <arg> Comma-delimited list of profiles
to activate
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path.
-q,--quiet Quiet output - only show errors
-rf,--resume-from <arg> Resume reactor from specified
project
-s,--settings <arg> Alternate path for the user
settings file
-T,--threads <arg> Thread count, for instance 2.0C
where C is core multiplied
-t,--toolchains <arg> Alternate path for the user
toolchains file
-U,--update-snapshots Forces a check for missing
releases and updated snapshots on
remote repositories
-up,--update-plugins Ineffective, only kept for
backward compatibility
-V,--show-version Display version information
WITHOUT stopping build
-v,--version Display version information
-X,--debug Produce execution debug output

Maven工程应用

基于命令行工程应用

基于命令行的工程应用,必须确保已经配置了Maven环境变量.

命令行创建工程

使用maven命令行创建一个maven工程.示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost /export ]$ mvn archetype:generate -B -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.1 -DgroupId=com.wuyu -DartifactId=wuyu-module -Dversion=1.0.0-SNAPSHOT -Dpackage=com.wuyu.module
[root@localhost /export ]$ tree wuyu-module
wuyu-module
├── pom.xml
└── src
├── main
│   └── java
│   └── com
│   └── wuyu
│   └── module
│   └── App.java
└── test
└── java
└── com
└── wuyu
└── module
└── AppTest.java

11 directories, 3 files
[root@localhost /export ]$ cd wuyu-module

参数说明

  • -B: 批量模式,使用该参数会跳过一个一个的交互输入
  • -DgroupId: 项目组织唯一的标识符
  • -DartifactId: 项目的唯一的标识符,对应项目的名称,即项目根目录的名称.
  • -Dversion: 生成的项目版本号
  • -Dpackage: 生成的工程包路径

命令行编译工程

修改编译使用的jdk版本, pom.xml文件中增加如下配置指定jdk编译的版本和生成的字节码版本:

  • maven.compiler.source
  • maven.compiler.source
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
[root@localhost wuyu-module ]$ cat pom.xml 
<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.wuyu</groupId>
<artifactId>wuyu-module</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>wuyu-module</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

编译生成的工程,查看编译后的结构:

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
41
42
43
44
45
46
47
48
49
50
51
[root@localhost wuyu-module ]$ mvn package
[root@localhost wuyu-module ]$ tree .
.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │   └── com
│   │   └── wuyu
│   │   └── module
│   │   └── App.java
│   └── test
│   └── java
│   └── com
│   └── wuyu
│   └── module
│   └── AppTest.java
├── target
│   ├── classes
│   │   └── com
│   │   └── wuyu
│   │   └── module
│   │   └── App.class
│   ├── generated-sources
│   │   └── annotations
│   ├── generated-test-sources
│   │   └── test-annotations
│   ├── maven-archiver
│   │   └── pom.properties
│   ├── maven-status
│   │   └── maven-compiler-plugin
│   │   ├── compile
│   │   │   └── default-compile
│   │   │   ├── createdFiles.lst
│   │   │   └── inputFiles.lst
│   │   └── testCompile
│   │   └── default-testCompile
│   │   ├── createdFiles.lst
│   │   └── inputFiles.lst
│   ├── surefire-reports
│   │   ├── TEST-com.wuyu.module.AppTest.xml
│   │   └── com.wuyu.module.AppTest.txt
│   ├── test-classes
│   │   └── com
│   │   └── wuyu
│   │   └── module
│   │   └── AppTest.class
│   └── wuyu-module-1.0.0-SNAPSHOT.jar
└── ~

33 directories, 13 files

可以看到编译后的结构入上图,target下有我们编译的字节码还有编译打包好的jar包wuyu-module-1.0.0-SNAPSHOT.jar.

命令行执行工程

1
2
[root@localhost wuyu-module ]$ java -cp target/wuyu-module-1.0.0-SNAPSHOT.jar com.wuyu.module.App
Hello World!

基于IDE的工程应用

这里演示使用IntelliJ IDEA创建Maven项目.

Maven创建单模块工程

【File】-【New】-【Project】-【Maven】-【勾选 Create from archetype】:

点击【Next】, 配置工程坐标:

点击【Next】,配置Maven信息:

点击【Next】, 配置工程名称, 示例中配置为: wuyu-module, 点击完成(选择新窗口打开刚才创建的示例工程).

Maven创建多模块工程

上面示例中我们创建了一个工程,改工程为单模块的. 实际开发中我们可能根据工程职责分成多个模块, 接下来展示如何构建多模块工程.

刚才的工程对于多模块中只有pom.xml文件有用,其它的src目录下的都没用,所以可以做如下操作:

  • 删除src以及其子目录
  • 修改pom.xml中packaging类型为pom.
  • 选中工程,右键:【New】-【Module】,然后创建子模块的定义.

创建jar格式的子模块

普通的jar模块,选择的maven类型为maven-archetype-quickstart

创建war格式的子模块

创建完后的多模块工程结构如下:

Maven统一依赖管理

maven版本统一管理采用<dependencyManagement>元素结点, 主要有两个作用,一个是集中管理项目的依赖项,另一个就是控制使用的依赖项的版本.

该节点主要应用于父pom, 里边托管所有要依赖的包依赖, 子包引入的时候, 采用dependencyManagement里边的包的子集的时候不需要指定版本.类似还有pluginManagement.用于统一管理maven的插件版本.

父类模块中dependencyManagement排除功能,同样会应用到到子模块.

说明: 右侧我们看到的Lifecycle模块是IDEA中提供的方便我们进行Maven命令执行的可视化工具, 支持单选和多选.

Maven依赖包作用域

Maven在引入依赖包的时候可以指定作用域,使用scope标签. scope的取值有compile(默认)、runtimetestprovidedsystemimport

  • compile: 默认作用范围,compile范围内的依赖项在所有情况下都是有效的,包括运行、测试和编译时(会被打到包里)。

  • runtime: 表示该依赖项只有在运行时才是需要的,在编译的时候不需要。这种类型的依赖项将在运行和test的类路径下可以访问(会被打到包里)。

  • test: 表示该依赖项只对测试时有用,包括测试代码的编译和运行,对于正常的项目运行是没有影响的(不会打到包里)。

  • provided: 表示该依赖项将由JDK或者运行容器在运行时提供,也就是说由Maven提供的该依赖项我们只有在编译和测试时才会用到,而在运行时将由JDK或者运行容器提供(不会打到包里)。

  • system: 当scope为system时,表示该依赖项是我们自己提供的,不需要Maven到仓库里面去找。指定scope为system需要与另一个属性元素systemPath一起使用,它表示该依赖项在当前系统的位置,使用的是绝对路径(不会打到包里)。

  • import: (Maven2.0.9及以上)import范围只适用于pom文件中的部分。表明指定的POM必须使用部分的依赖。因为依赖已经被替换,所以使用import范围的依赖并不影响依赖传递

Maven依赖冲突排除

我们可能经常会遇到这样一个问题:我们的项目有两个依赖项:A & B,而且A和B同时依赖了C,但不是同一个版本。那么我们怎么办呢?

添加检查插件

1
2
3
4
5
6
7
8
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>

然后运行:mvn project-info-reports:dependencies,来查看依赖项报告.

去除依赖项

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.0.5.RELEASE</version>
<exclusions>
  <exclusion>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
  </exclusion>
</exclusiongs>
</dependency>

Maven读书笔记

参考资料