Maven学习笔记

Maven学习笔记封面

Maven学习笔记

Maven学习笔记

1.环境配置

已经配置过JAVA环境及Maven环境变量的配置工作

mvn- v

查看当前mvn版本及系统环境状态

mvn help:system

打印出所有的JAVA系统属性和环境变量

~/.m2

~ 代表用户目录
.m2 文件夹下有Maven的全部资源文件

m2eclipse插件

详情参考另一篇Maven博客中插件安装方法Maven
组件用途参考P10-P11

不要使用ME自带的Maven插件

2.入门使用

编写pom

POM(Project Object Model,项目对象模型)

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<porject 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.juvenxu.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Hello World Project</name>
</project>

groupId

定义了项目属于哪个组

artifactId

定义了当前Maven项目在组中唯一的ID

version

项目版本,SNAPSHOT 表示快照,项目处于开发中

name

一个对于用户更为友好的项目名称
Maven优点,项目对象模型最大程度地与实际代码相独立,解耦或者正交性。

Helloworld

编写测试代码

加入junit依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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.juvenxu.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Hello World Project</name>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>

mvn clean compile
项目根目录下执行后进行项目编译
mvn clean test
Maven测试命令,先自动执行项目主资源处理,主代码编译,测试资源处理,测试代码编译工作。
mvn clean package
默认打包类型为jar,即jar插件的jar目标将项目的主代码打包成一个 项目名.jar 的文件。
mvn clean install
复制被打包的jar到其他的项目中需要安装。

在ME中使用maven项目操作依旧参照上篇博客

#坐标和依赖

一个构件必须明确定义自己的坐标,一组Maven坐标是通过一些元素定义的:
groupId
artifactId
version
packaging | 可选
classifier | 不能直接定义

groupId

当前Maven项目隶属的实际项目。一个实际项目往往会被划分成很多模块。只定义到组织级别。

artifactId

定义实际项目中的一个Maven项目。

version

版本。

packaging

打包方式,默认为jar。

classifier

帮助定义构建输出的一些附属构件。

依赖范围

Compile
编译依赖范围。默认值,对于编译、测试、运行三种classpath都有效。
Test
测试依赖范围。典型的例子是JUnit,只在编译测试代码及运行测试的时候才需要。
Provided
已提供依赖范围。典型例子是servlet-api,对于编译和测试classpath有效,但在运行时无效。
Runtime
运行时依赖范围。典型例子是JDBC驱动实现,对于测试和运行classpath有效,但在编译主代码时无效。
System
系统依赖范围。必须通过systemPath元素显式地置顶依赖文件的路径。由于此依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植。

1
2
3
4
5
6
7
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>

Import
导入依赖范围。不会对三种classpath产生实际的影响。

依赖范围(Scope) 对于编译classpath有效 对于测试classpath有效 对于运行时classpath有效 例子
compile Y Y Y spring-core
test - Y - JUnit
provided Y Y - servlet-api
runtime - Y Y JDBC驱动实现
system Y Y - 本地的,Maven仓库之外的类库文件

传递性依赖

Maven会自动添加依赖关系,如使用Spring-Framwork的时候不用考虑它依赖了什么,也不用担心引入多余的依赖。

传递性依赖和依赖范围

假设A依赖于B,B依赖于C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。
下表左边一列表示第一直接依赖范围,最上一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围:

- compile test provided runtime
compile compile - - runtime
test test - - test
provided provided - provided provided
runtime runtime - - runtime

依赖调解

有时候我们只关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。
Maven依赖调解的第一原则:路径最近者优先
例如:
项目A有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0)
其中X(1.0)的路径长度为3,X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
Maven依赖调解的第二原则:第一声明者优先
在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。
例如:
项目A有以下依赖关系:A->B->Y(1.0)、A->C->Y(2.0),Y(1.0)和Y(2.0)依赖路径长度是一样的,都是2。顺序最靠前的那个依赖优胜。

可选依赖

假设有这样一个依赖关系,项目A依赖于项目B,B依赖于项目X和Y,B对于X和Y的依赖都是可选依赖:A->B、B->X(可选)、B->Y(可选)。根据传递性依赖的定义,如果所有这三个依赖的范围都是compile,那么X、Y就是A的compile范围传递性依赖。然而,由于这里X、Y是可选依赖,依赖将不会得以传递,换句话说,X、Y将不会对A有任何影响。
可能项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。比如B是一个持久层隔离工具包,支持多种数据库,构建时需要两种数据库的驱动程序,但在使用这个工具包的时候,只会依赖一种数据库。

排除依赖

传递性依赖会给项目隐式的引入很多依赖,这极大地简化了项目依赖的管理,但是有些时候这种特性也会带来问题。
例如,当一个项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另外一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性就会直接影响到当前的项目。

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
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0.0</version>

<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-c</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-c</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</project>

exclusions 元素声明排除依赖, exclusions 可以包含一个或者多个 exclusion 子元素,因此可以排除一个或者多个传递性依赖。

归类依赖

在升级项目的时候只需要修改一处,类似于配置文件。

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
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-email</artifactId>
<name>Account Email</name>
<version>1.0.0-SNAPSHOT</version>

<properties>
<springframework.version>2.5.6</springframework.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>

</project>

优化依赖

Maven会自动解析所有项目的直接依赖和传递依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖冲突,异能进行调节,以确保任何一个构件只有唯一的版本在依赖中存在。最后得到的那些依赖被称为已解析依赖
依赖树。

使用Maven构建Web应用

指定打包方式为war

使用Cargo实现自动化部署

cargo-maven2-plugin 主要服务于自动化部署

部署至本地Web容器

standalone 模式。Cargo会从Web容器的安装目录复一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。
existing 模式。用户需要指定现有的Web容器配置目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat7x</containerId>
<home>D:\apache-tomcat-7.0.67</home>
</container>
<configuration>
<type>standalone</type>
<home>${project.build.directory}/tomcat7x</home>
<properties>
<cargo.servlet.port>8080</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>

部署至远程Web容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat7x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password>admin</cargo.remote.password>
<cargo.tomcat.manager.url>http://localhost:8080/manager</cargo.tomcat.manager.url>
</properties>
</configuration>
</configuration>
</plugin>
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2017/06/22/2017-06-22-Maven学习笔记/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
支付宝打赏
微信打赏