前言
Maven仅仅是个打包工具而已,个人觉得没有太大必要花费在打包工具上,这里就列举一下个人觉得会常用标签的使用就好了,原理啥的基本就不太会去深度了解了,如果以后遇到需了解Maven工作原理的工作的话,到时候一定分享出来。
pom结构
前面那篇博客已经展示过了,这里就在展示一下,官网上也有文档可以查看,链接:Maven官网pom.xml
parent标签
这个标签用的最多是在使用Spring Boot项目以及父子项目的用的最多,
SpringBoot示例:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.15.RELEASE</version>
</parent>
父子项目示例:
这里module标签意思就是该父项目有哪些模块的意思,值为子模块的文件夹的名称,而不是artifactId,不然找不到对应的子模块,而且在父模块中的packaging标签值为pom,表示这是一个父类项目。
坐标
Maven中坐标是Jar包的唯一标识,在pom.xml中指定坐标的标签元素包括:groupId,artifactId,version,packaging
元素 | 描述 | 说明 |
groupId | 定义当前模块隶属的实际Maven项目 | 中小企业常常直接对应公司/组织 |
artifactId | 定义实际项目中的一个模块 | 唯一标识一个模块 |
version | 定义当前项目所在的版本 | SNAPSHOT 表示不稳定的版本。 LATEST 指最新发布的版本,可能是个发布版,也可能是一个snapshot版。 RELEASE 指最后一个发布版。 |
packaging | 定义Maven项目打包方式 | 有jar(默认)、war、pom(表示为父模块)、maven-plugin(当前项目为插件)等. |
classifier | 附属构件(如javadoc、sources) | 须有附加插件的帮助 |
properties属性标签
这个标签里面可自定义标签属性,也可覆盖默认标签属性,示例:
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>5.1.16.RELEASE</spring.version>
</properties>
....
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency>
</dependencies>
自定义属性可以在maven的生命周期中使用,最常用的就是在default-resources中使用,用来替换properties文件中的${}值。
Maven自己会有一些内置属性:
${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为target
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件的任意节点的内容
dependency依赖标签
这个标签下放的就是当前项目依赖jar的坐标。
如果我想引入一下MySQL的驱动包:
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version><scope>compile</scope>
</dependency>
这里有个依赖作用域scope,一般有以下依赖范围:
- compile:默认范围,用于编译,依赖的jar在打包时会包含进去
- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath,依赖的jar在打包时不会包含进去
- runtime:在执行时需要使用,依赖的jar在打包时会包含进去
- test:用于test任务时使用,依赖的jar在打包时不会包含进去
- system:需要外在提供相应的元素。通过systemPath来取得,一般该作用域用来引入外部jar包
在使用system作用域的时候,使用systemPath标签指定外部元素路径,如:
<systemPath>${project.basedir}/lib/sdk-1.0.jar</systemPath>//项目根路径下
在依赖标签里面还有一个标签属性optional:该标签默认值为false指的是父子项目之间的是否传递(之前在看Mybatis源代码的时候,下载下来后的pom.xml里面就会有这个标签),如果父项目引入一个依赖并且optional标签设置为true的话,那么子项目打包的时候也会打包进去,如果设置为false的话,那么就不会打包进去。
依赖冲突解决:
在引入依赖的时候会存在一个问题,就是依赖传递,如果在项目中引入多个重复的依赖,那么jvm只能拿到一个版本的依赖,其他的版本的依赖就会被抛弃,所以Maven在处理这个上是有一定的顺序的,先看一下示例:
如果有个项目pom.xml引入fastjson包的依赖如下:
则取舍规则如下:
1、路径最短原则:product和customer里的fastjson引用路径较短,路径为两步 ;pay项目里的fastjson引用路径较长,路径为三步。因此pay中的fastjson被淘汰;
2、同路径长度下,谁先声明谁优先: product和customer中的fastjson路径相同,那么就看在pom中是先声明product还是先声明customer,谁先用谁的。
profiles标签
主要应用的场景:开发环境和测试环境的配置是不一致的,为了打包方便,一般我们会将配置文件的写在一个properties文件中,如下:
在打包的时候指定是测试环境还是开发环境进行不同的打包,实现这样的一个功能就是使用profiles标签了,先将两种不同环境的数据录入到profiles标签中,如下所示(activeByDefault为默认配置):
此定义即指,当mvn命令执行时,我们需要通过加上 -P dev或者-P test方式传入我们的需要指定的profile的id:dev/test选择,会导致properties里的变量值含义不同,这个操作需要在build标签中添加一个资源复制:
dependencyManagement标签
这个标签是作为版本号管理使用的,基本上都是用于父项目中,定义好全局统一的版本号,在子项目中就只需要引入groupId以及artifactId了,在SpringBoot的父模块中就是使用的这个作为统一管理的。
build标签
该标签主要是用来打包时做一些处理功能,像资源文件的复制,选择指定的插件以及最终打包的jar包名称等。
finalName
当前应用工程打包的jar名称
pluginManagement标签
当前标签和dependencyManagement的作用是一致,在父模块当中定义好版本号,在子模块当中直接引用即可
plugin标签
当前标签为插件标签,在上篇博文当中已经提到了Maven生命周期中对应的执行插件有哪些,而插件也是一个jar包,所以引入也是需要通过坐标进行引入的,示例如上。
后面我会发布一篇博客专门讲解Maven插件的。
distributionManagement
该标签是在Maven的deploy阶段,即将当前项目推送到远程私服的仓库上,以供于他人使用,一般比较大型的公司都会有自己的私服仓库,公司内部自己也会开发一些组件啥的,开发完之后需推送到公司的私服仓库当中,私服后面我也会有一片博客讲解这个东西,在推送的过程中也可以指定推送哪种类型的仓库
还有两种常用的标签:repositories和pluginRepositories,用法如下:
repositories:即指定当前项目依赖引入jar使用的仓库地址,如果在Maven的settings.xml中指定好镜像仓库和依赖仓库后,这里其实是可以不需要指定的,但是如果某些项目需要的依赖仓库不在settings.xml的配置文件里面,可以在pom.xml中手动指定仓库。
pluginRepositories:即指定当前项目插件依赖引入jar使用的仓库地址。功能同上。
mirrors
还有个settings.xml里面的镜像标签需要提一下,Maven仓库镜像是会拦截所有只想仓库的路径,转向到镜像当中的仓库,即如果没有配置镜像的话,那么Maven下载依赖包会直接去远程中央仓库中下载,而如果配置了镜像,那么就会被镜像拦截,转发到镜像指定的仓库下载依赖,和镜像标签一起使用的还有mirrorOf标签,该标签是可以指定哪些仓库可以被镜像拦截
<!--匹配所有仓库请求,即将所有的仓库请求都转到该镜像上-->
<mirrorOf>*</mirrorOf> <!--将仓库jcenter和repo2的请求转到该镜像上,使用逗号分隔多个远程仓库。 -->
<mirrorOf>jcenter,repo1</mirrorOf> <!--匹配所有仓库请求,jcenter除外,使用感叹号将仓库从匹配中排除。-->
<mirrorOf>*,!jcenter</miiroOf> <!-- settings.xml中的仓库 -->
<repository><id>jcenter</id><url>https://jcenter.bintray.comt</url>
</repository>
<repository><id>repo1</id><url>https://repo1.maven.org/maven2</url>
</repository>
下面列举一些镜像地址:
<!-- 阿里云的镜像站--><mirror><id>nexus-aliyun</id><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- maven官方运维仓库 -->
<mirror> <id>repo2</id> <name>Mirror from Maven Repo2</name> <url>http://repo2.maven.org/maven2/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- maven在UK架设的仓库-->
<mirror> <id>ui</id> <name>Mirror from UK</name> <url>http://uk.maven.org/maven2/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- JBoss的仓库 -->
<mirror> <id>jboss-public-repository-group</id> <mirrorOf>central</mirrorOf> <name>JBoss Public Repository Group</name> <url>http://repository.jboss.org/nexus/content/groups/public</url>
</mirror>
Maven不仅仅是以上的那些标签属性,在此只是列出来个人觉得平常使用的比较多的标签。