概述
maven主要致力于让项目构建更加简单,提供统一的构建系统,提供优质的项目信息
pom文件样例
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 指定pom的版本(即pom文件的格式),目前版本号只有4.0.0 -->
<modelVersion>4.0.0</modelVersion>
<!-- The Basics 基础标签-->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- Build Settings -->
<build>...</build>
<reporting>...</reporting>
<!-- More Project Information -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- Environment Settings -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
The Basics 基础属性
maven定位三要素
groupId:代表一个组织或者一个项目,如公司或者公司的某个项目,以倒序的方式写,如com.baidu或者com.baidu.brower
artifactId:代码具体的项目或者模块,如果groupId划分是组织,那么这个应该写具体的项目,如果groupId是一个大的项目,这边应该划分到具体的模块
version:代表具体的版本号
通过这个三个最基本的参数,我们就可以定位到具体需要使用的jar包
packing打包方式
默认值:jar
可选项:pom,jar,war,ejb,ear,rar,maven-plugin
dependencies 依赖管理
- dependency样例
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
...
</dependencies>
...
</project>
- 三要素:
groupId,artifcatId,version定位三要素,来确定一个依赖
- type 类型:
对于所选依赖的类型,即我们前面项目可以打成多种包,jar,pom之类。。。同样我们依赖的时候,也可以选择依赖的类型,默认是jar
- scope 范围:
指定依赖生效的范围,maven其实有三套classpath,即编译,测试,运行(即打包后生成的target文件中的lib,是你实际运行时候所需要依赖的jar)
- compile
默认选项是compile,指在代码编译,运行,测试三个阶段都生效。怎么理解这个,就是在你各个阶段的classpath里面都能找到这个依赖
- runtime
这个选项的意思是只在运行和测试的时候生效,不需要经过编译。个人感觉比如动态加载某个类的时候才需要,比如常见的是数据库驱动。
正常情况下,你代码里加载驱动的时候都是class.forname(“xxx”),此时编译期间可以不用,但是你实际运行的时候是需要的,测试的时候也要要真正具体的驱动来生效。
- test
test只在测试和编译的时候生效,在实际运行的时候不生效,因为实际target的lib包中不包含这些jar包
- provided
跟compile一样,三个阶段都生效,但是实际的打包的时候target的lib包里面不包含这个jar包,由外部提供比如由jdk或者容器提供
- system
跟provided相似,不过是引用本地jar包,与systemPath一起使用,实际打包的时候也不含这个jar包,如果想要打进去需要配置额外的插件
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
- optional
默认为true, true or flase,代表这个依赖是否传递
依赖的传递性
在上述scope中,如果没有配置optional为false, compile和runtime是会依赖传递的,比如A依赖了B,B依赖了C,那么A也能使用C,这就是依赖的传递性
依赖的调解
假如一个项目中,存在如下依赖
A->B->C(1.2.0)
A->D->F->C(2.3.0)
依赖都会传递,同时依赖了两个版本的C jar包,此时会怎么处理?遵循以下两个原则:
- 就近原则 即跟A依赖关系最近的优先使用,上述中,A->B->C,只有两层,所以他优先生效
- 优先声明原则 如果两个路径长度一样怎么办呢?那就是谁先声明的谁生效,即pom文件谁在前面谁生效
依赖的冲突解决
由于依赖调解,有时候也会导致依赖冲突,最常见的就是日志组件的冲突,大家的实现都不相同,有的是log4j,有的是logback,此时我们需要将其他的日志组件排除掉,在dependency中添加如下标签,只需groupId和artifactId即可。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>