maven总结

简介

maven是一个Apache下由java开发的开源项目。基于对象模型的概念(POM),Maven利用能管理一个项目的构建、报告和文档等步骤。

需求

当写一个项目的时候往往需要引入第三方依赖包,但是一个第三方包可能又要依赖其他的包,一旦依赖过多,就会给开发人员造成很大的负担,而且容易出错。maven使用一个仓库存储需要的第三方库,而且可以自动解决依赖问题。构建过程枯燥重复,使用maven可以减轻构建的烦恼。

安装

官网下载相应系统的文件,解压放入一个目录,设置环境变量。

也可以使用IDEA中自带的maven,一般使用自己安装的maven,可以在File | Settings | Build, Execution, Deployment | Build Tools | Maven中修改配置。

在maven的settings.xml中添加maven镜像,国内下载依赖会更快。

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

使用

常用命令

构建中常用的命令(需要进入到与pom.xml同目录下):

  • mvn clean :清理之前产生的class文件
  • mvn compile :编译项目
  • mvn test-compile:编译测试文件
  • mvn test:测试
  • mvn package :将项目打包为
  • mvn install :安装到本地仓库

目录结构:

约定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my-app
|-- pom.xml
`-- src
|-- main
| `-- java
| `-- com
| `-- mycompany
| `-- app
| `-- App.java
`-- test
`-- java
`-- com
`-- mycompany
`-- app
`-- AppTest.java

目录 目的
${basedir} 存放pom.xml和所有的子目录
${basedir}/src/main/java 项目的java源代码
${basedir}/src/main/resources 项目的资源,比如说property文件,springmvc.xml
${basedir}/src/test/java 项目的测试类,比如说Junit代码
${basedir}/src/test/resources 测试用的资源
${basedir}/src/main/webapp/WEB-INF web应用文件目录,web项目的信息,比如存放web.xml、本地图片、jsp视图页面
${basedir}/target 打包输出目录
${basedir}/target/classes 编译输出目录
${basedir}/target/test-classes 测试编译输出目录
Test.java Maven默认的本地仓库目录位置

创建java项目

mvn archetype:generate -DgroupId=com.companyname.bank -DartifactId=consumerBanking -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
参数:

  • -DgourpId: 组织名,公司网址的反写 + 项目名称
  • -DartifactId: 项目名-模块名
  • -DarchetypeArtifactId: 指定 ArchetypeId,maven-archetype-quickstart,创建一个简单的 Java 应用
  • -DinteractiveMode: 是否使用交互模式

pom.xml

pom(project object model)项目对象模型

pom.xml是核心文件:

坐标

  • groupId:公司域名的倒叙+项目
  • artifactId:模块名
  • version :版本号

这三者唯一确定了一个jar包
举例:

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

在本地仓库中路径:org/springframework/spring-core/4.1.7.RELEA/spring-core-4.1.7.RELEASE.jar

仓库

  • 本地仓库
  • 中央仓库
  • 镜像仓库

scope

  • compile,缺省值如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。
  • provided,期望JDK、容器或使用者会提供这个依赖。不是传递性的,也不会被打包。如servlet.jar。
  • runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。
  • test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。
  • system,类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。

构建生命周期

  • validate - 验证项目是否正确并且所有必要信息都可用
  • compile - 编译项目的源代码
  • test - 使用合适的单元测试框架测试编译的源代码。这些测试不应要求打包或部署代码
  • package - 获取已编译的代码并将其打包为可分发的格式,例如JAR。
  • verify - 对集成测试结果进行任何检查,以确保满足质量标准
  • install - 将软件包安装到本地存储库中,以便在本地用作其他项目的依赖项
  • deploy - 在构建环境中完成,将最终包复制到远程存储库以与其他开发人员和项目共享。

在执行每一个周期都会先执行之前的周期

依赖冲突

在maven中依赖会传递,A依赖B,B依赖C,在A中会依赖B和C。如果两个jar包的版本不同,就出现了冲突。maven会自动解决冲突,两个原则:

  • 最短路径(依赖路径短的)
  • 先声明(如果路径长度一致,后声明的会失效)

使用mvn dependency:tree查看所有的依赖树

排除依赖

如果想要排除某个依赖,可以直接排除掉

1
2
3
4
5
6
7
8
9
10
11
<dependency>      
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
<version>0.94.17</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

继承

统一管理版本,子pom依赖父pom,当然你可以复写父pom的内容。

聚合

使用modules标签,聚合模块

一个例子:一个父工程A,下面有子模块B,C,D三个子模块
A的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
<!--聚合模块-->
<modules>
<module>B</module>
<module>C</module>
<module>D</module>
</modules>
<!--依赖管理,管理pom的依赖版本问题,在子pom中不必-->
<dependencyManagement>

<dependencies>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
</dependencies>

</dependencyManagement>

...

B的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
<!--认父亲-->
<parent>
<artifactId>A</artifactId>
<groupId>com.zzx.maven</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--可以自定义属性-->
<properties>
<junit.version>4.11</junit.version>
</properties>



<!--可以忽略version-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<!--将会用于依赖冲突解决方案-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>

</dependencies>

C的pom.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<!--版本变化-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
</dependencies>

D依赖B,C,引入B,C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<dependencies>
<!--此时在B和C中都依赖了sl4j,不过版本不同-->
<dependency>
<groupId>com.zzx.maven</groupId>
<artifactId>B</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.zzx.maven</groupId>
<artifactId>C</artifactId>
<version>1.0-SNAPSHOT</version>

</dependency>

</dependencies>

通过mvn dependency:list查看依赖,可以看见是依赖的B中的sl4j的版本,当交换两个依赖的顺序,再次查看会发现依赖的sl4j版本改变了。

Error

在我未install A时,install D会出错。解决办法:先install A(父pom)

1
2
3
4
5
6
7
8
9
10
11
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.283 s
[INFO] Finished at: 2019-04-30T19:20:18+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project D: Could not resolve dependencies for project com.zzx.maven:D:jar:1.0-SNAPSHOT: Failed to collect dependencies at com.zzx.maven:B:jar:1.0-SNAPSHOT: Failed to read artifact descriptor for com.zzx.maven:B:jar:1.0-SNAPSHOT: Could not transfer artifact com.zzx.maven:B:pom:1.0-SNAPSHOT from/to jdk18 (http://www.myhost.com/maven/jdk18): Failed to transfer file http://www.myhost.com/maven/jdk18/com/zzx/maven/B/1.0-SNAPSHOT/B-1.0-SNAPSHOT.pom with status code 500 -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]

当然maven还用其他的很多功能,比如插件。

文章作者: gentlezuo
文章链接: http://gentlezuo.github.io/2019/04/29/maven总结/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 gentlezuo的博客