笔记。


安装

官网下载安装包,解压。

bin目录包含mvn的运行脚本
boot目录包含一个类加载器的框架
conf是配置文件目录

配置环境变量M2_HOME
变量值:E:\maven\apache-maven-3.6.1

Path中添加%M2_HOME%\bin

cmd输入mvn -v

输出

1
2
3
4
Maven home: E:\maven\apache-maven-3.6.1\bin\..
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: E:\JDK\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

即安装成功。

结构

1
2
3
4
5
6
7
8
src
-main
-java
-package
-test
-java
-package
resources

新建结构E:\maven\code\maven01\src\main\java\com\jinger\maven01\model
在这里新建HelloWorld.java

1
2
3
4
5
6
7
package com.jinger.maven01.model;

public class HelloWorld{
public String sayHello(){
return "Hello World!";
}
}

新建结构E:\maven\code\maven01\src\test\java\com\jinger\maven01\model
在这里新建HelloWorldTest.java

1
2
3
4
5
6
7
8
9
10
11
package com.jinger.maven01.model;

import org.junit.*;
import org.junit.Assert.*;

public class HelloWorldTest{
@Test
public void testHello(){
Assert.assertEquals("Hello World!",new HelloWorld().sayHello());
}
}

在E:\maven\code\maven01新建pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.jinger.maven01</groupId>
<artifactId>maven01-model</artifactId>
<version>0.0.1SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>

groupId的值是项目包名
artifactId的值是模块名

cmd里mvn compile编译,第一次安装会自动下载相关依赖。

mvn test测试,显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.jinger.maven01.model.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.068 s
[INFO] Finished at: 2019-07-28T17:26:39+08:00
[INFO] ------------------------------------------------------------------------

跟目录下生成了target文件夹

mvn package打包

1
2
3
4
5
6
7
[INFO] Building jar: E:\maven\code\maven01\target\maven01-model-0.0.1SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:46 min
[INFO] Finished at: 2019-07-28T17:29:43+08:00
[INFO] ------------------------------------------------------------------------

生成了jar包。

基础

mvn -v 查看maven版本
compile 编译
test 测试
package 打包

clean 删除target
install 安装jar包到本地仓库中

新建结构E:\maven\code\maven02\src\main\java\com\jinger\maven02\util
在这里新建Speak.java

1
2
3
4
5
6
7
8
9
package com.jinger.maven02.util;

import com.jinger.maven01.model.HelloWorld;

public class Speak{
public String sayHi(){
return new HelloWorld().sayHello();
}
}

新建结构E:\maven\code\maven02\src\test\java\com\jinger\maven02\util
在这里新建SpeakTest.java

1
2
3
4
5
6
7
8
9
10
11
package com.jinger.maven02.util;

import org.junit.*;
import org.junit.Assert.*;

public class SpeakTest{
@Test
public void testHello(){
Assert.assertEquals("Hello World!",new Speak().sayHi());
}
}

mvn compile编译

1
错误:[ERROR] /E:/maven/code/maven02/src/main/java/com/jinger/maven02/util/Speak.java:[3,32] 程序包com.jinger.maven01.model不存在

进入maven01文件夹执行mvn install发送到本地仓库中
在pow.xml加入依赖项

1
2
3
4
5
<dependency>
<groupId>com.jinger.maven01</groupId>
<artifactId>maven01-model</artifactId>
<version>0.0.1SNAPSHOT</version>
</dependency>

完整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
<?xml version="1.0" encoding="UTF-8"?>

<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.jinger.maven02</groupId>
<artifactId>maven02-model02</artifactId>
<version>0.0.1SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<dependency>
<groupId>com.jinger.maven01</groupId>
<artifactId>maven01-model</artifactId>
<version>0.0.1SNAPSHOT</version>
</dependency>
</dependencies>
</project>

自动创建目录骨架

archetype插件
创建目录的两种方式:

  1. mvn archetype:generate
    选1389 Choose org.apache.maven.archetypes:maven-archetype-quickstart version 再选最新版

Confirm properties configuration:
groupId: com.jinger.maven03
artifactId: maven03-service
version: 1.0.0SNAPSHOT
package: com.jinger.maven03.service

  1. 1
    2
    3
    4
    mvn archetype:generate -DgroupId=组织名, 公司网址的反写+项目名
    -DartifactId=项目名-模块名
    -Dversion=版本号
    -Dpackage=代码所存在的包名

坐标和仓库

构件通过坐标作为其唯一标识

修改镜像仓库位置:
E:\maven\apache-maven-3.6.1\conf
打开settings.xml
146行增加

1
2
3
4
5
6
<mirror>
<id>maven.net.cn</id>
<mirrorOf>central</mirrorOf>
<name>central mirror in China</name>
<url>http://maven.net.cn/content/groups/public</url>
</mirror>

这个源好像不太行,换成阿里云的可以

1
2
3
4
5
6
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf> *
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>

修改默认本地仓库位置
49行增加

1
<localRepository>E:/maven/repo</localRepository>

将该settings.xml复制到repo文件夹下。

在Eclipse中的使用

新版Eclipse自带Maven插件。
新建New-Other-Maven Project,选择quickstart模板。
Group Id:com.jinger.hi
Artifact Id:hi

建成后,对pom.xml右键,Run As-2 Maven build …
在Goals中填入compile

再在Goals中填入package
jar包构建成功

Maven生命周期和插件

完整的项目构建过程包括:
清理、编译、测试、打包、集成测试、验证、部署

maven生命周期:
clean 清理项目
default 构建项目
site 生成项目站点

clean清理项目

pre-clean 执行清理前的工作
clean 清理上一次构建生成的所有文件
post-clean 执行清理后的文件

default 构建项目(最核心)

compile test package install

site 生成项目站点

pre-site 在生成项目站点前要完成的工作
site 生成项目的站点文档
post-site 在生成项目站点后要完成的工作
site-deploy 发布生成的站点到服务器上

举例
在pom.xml新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

run as - maven build …
clean package

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
pom.xml:maven项目的核心管理文件,用于项目描述、组织管理、依赖管理、构建信息的管理,Pom中包含了许多的标签。
Pom.xml的常用元素:
<project>是pom.xml的根元素,包含了pom的一些约束信息。
<modelVersion>是一个固定的版本,也是必须的元素,指定了当前pom的版本。
坐标的信息由以下标签组成:
<groupId>主项目标识,公司网址+项目名组成</groupId>
注意:maven的项目和实际的项目不是一一对应关系,maven项目体现的是模块化的概念,因此一个实际项目往往会划分成很多的模块。
<artifactId>一个模块的标识,项目名+模块名进行标识</artifactId>

<version>第一个0标识大版本号,第二个0表示分支版本号,第三个0表示小版本号,一般形式可以写为0.0.1snapshot,snapshot快照、alpha内部测试、beta公测、Release稳定、GA版本正式发布<version>

<packaging>maven项目打包的方式,默认打包是jar,、其他类型war、zip、pom等<packaging>

其他标签:
<name>项目的描述名,一般是在产生对象文档时候才会使用</name>
<url>项目的地址</url>
<description>项目的描述</description>
<developers>开发人员的列表</developers>
<licenses>许可证的信息,比如经常用到的开源框架,它都会有一些许可证的信息</licenses>
<organization>组织信息</organization>

<dependencies>依赖列表

<dependencies>
依赖项(可以包含多个)
依赖项用坐标确定依赖的位置
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<type>类型</type>
<scope>依赖的范围(比如上面写的junit的测试范围是test,只在测试的依赖范围内有用,在主代码中引用junit这个类,它就会报错)</scope>
<optional>设置依赖是否可选(默认是false,子项目默认是false时,子项目默认是继承的,如果为true,子项目必须显示的引入该依赖)</optional>
<executions>
排除依赖的传递列表(可以排除多个依赖,比如Ajar包依赖Bjar包,Bjar包又依赖Cjar包,C对于A来说就是传递依赖,如果A不想依赖C,就使用该标签)
<execution></execution>
</executions>
</dependencies>

<dependencyManagementy>依赖的管理</dependencyManagementy>
<dependencies>
<dependency>
</dependency>
</dependencies>

<dependencyManagement>依赖的管理,也可以通过<dependencies>声明依赖列表,通过<dependency>包含多个依赖,但是它并不会被运行,也就是说它不会被引入到实际的依赖当中,该标签一般主要用于定义在父模块中,供子模块继承用的。比如之前多个maven项目中,都使用到junit,我们就可以抽象出一个父类的模块,然后在父类模块中对junit进行一个定义,其他子模块直接继承该父模块即可。

<build>
插件列表
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</plugin>
</plugins>
</build>

<parent>用于子模块对父模块的pom的继承</parent>
<modules>指定多个模块一起编译</modules>

scope

三种classpath:

  1. 编译
  2. 测试
  3. 运行

compile:默认的范围,编译测试运行都有效
provided:在编译和测试时有效
runtime:在测试和运行时有效
test:只在测试时有效
system:与本机系统相关联,可移植性差
import:导入的范围,它只使用在dependencyManagement中,表示从其它的pom中导入dependency的配置

依赖

依赖的传递:
多个项目依次依赖,A<-B<-C,后面的引入前面的项目坐标
要把前面的项目编译、打包、安装后,后面的项目才能运行build

短路冲突:
1、短路优先
A->B->C->X(jar)
A->D->X(jar)

先解析下面的

2、先声明优先
如果路径长度相同,则谁先声明,先解析谁

聚合和继承

  1. 项目的继承
    在父类项目中使用dependencyManagement对依赖进行管理,但是并不会使用依赖,子类需要使用parent标签,来引用父类中的依赖,一般可以将版本号在父类中进行声明,子类无需声明版本号,这样可以保证子类和父类版本号一致。

  2. 项目的聚合
    将packaging打包方式改为pom,使用modules标签,引入其他项目

    1
    2
    3
    4
    5
    <modules>    
    <module>../A</module>
    <module>../B</module>
    <module>../C</module>
    </modules>

构建web项目

新建项目,模板选择webapp。
GroupId: com.jinger.webdemo
Artifact Id:webdemo

建成后,在Navigator中新建src/main/javasrc/test/java`src/test/resources`文件夹

在Project Explorer中对项目右键Build Path-Configure Build Path-Source,确保Output folder是webdemo/target/classes

项目属性-Project Facets
(没有这一项请下载输入http://download.eclipse.org/releases/oxygen ,选择Web, XML, Java EE and OSGi Enterprise Development 安装即可。)
勾选Dynamic Web Module
最终发布产品时不需要测试代码,项目属性-Deployment Assemnly,remove相关测试文件。

在pom.xml的下添加

1
2
3
4
5
6
7
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.16.v20140903</version>
</plugin>
</plugins>

run as build jetty:run
浏览器输入http://localhost:8080/
显示Hello World!

在打包成功后使用jetty:run来运行jetty服务

标签下

1
2
3
4
5
6
7
8
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>

run as build clean package
浏览器输入http://localhost:8080/
显示Hello World!

使用tomcat同理。