Maven是每个Java程序都会遇到的包管理工具,今天整理一下Maven的相关知识,从青铜到王者,一文全了解
官方网站说了好多,整的多复杂一样,简单说:maven是一个管理包的工具。
Maven 存在的必要性是什么呐?想想开源的jar包如此之多,版本又如此之多,在没有Maven之前,我们管理jar包全部都是下载之后创建一个lib的文件夹,然后项目进行引用,在其他的项目成员需要修改一个jar的时候需要到处拷贝,在部署的时候也很麻烦,问题存在就要解决,因此出现了Maven,统一管理,统一的仓库,只需要配置是要哪个版本的包,直接下载就够了,不用拷贝,是不是很方便。
现在大的问题解决了,怎么定位一个jar包呐?
File ->新建->project
勾选从原型(模板)创建,选择maven-archetype-qiuckstart
填入项目的名字,和groupId (公司域名反过来,如com.alibaba)
选择本地仓库的位置,和自定义的setting配置
一路finish,然后等待idea 创建模板项目就好了。
Maven 仓库有三种类型:
当我们执行 Maven 构建命令时,Maven 开始按照以下顺序查找依赖的库:
阿里云仓库配置:
<repositories>
<repository>
<id>central</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public/</url>
<layout>default</layout>
<!-- 是否开启发布版构件下载 -->
<releases>
<enabled>true</enabled>
</releases>
<!-- 是否开启快照版构件下载 -->
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
举个例子:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
可以通俗理解为lifecyle 是一个公司,phrase 是具体的部门,goal 是一个项目,Mojo 是项目内部的人,其他的都是管理层级,具体的执行还是人。
一个goal是独立的,它可以被绑定到多个phase中去,也可以一个phase都没有。如果一个goal没有被绑定到任何一个lifecycle,它仍然可以直接被调用,而不是被lifecycle调用。
因此可以这样理解phase与goal的关系:
goal可以通俗理解为一个项目。
clean生命周期每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。有Clean生命周期,也有clean阶段。Clean生命周期一共包含了三个阶段:
"mvn clean" 中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,"mvn clean"等同于 mvn pre-clean clean ,如果我们运行 mvn post-clean ,那么 pre-clean,clean 都会被运行。这是Maven很重要的一个规则,可以大大简化命令行的输入
执行phase实际执行的是goal。如果一个phase没有绑定goal,那这个phase就不会被执行。
<plugin>
<groupId>com.mycompany.example</groupId>
<artifactId>display-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>process-test-resources</phase>
<goals>
<goal>time</goal>
</goals>
</execution>
</executions>
</plugin>
一个生命周期包含一些列的步骤,当执行生命周期的时候,会把所有的步骤执行一次
官方文档:
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
http://maven.apache.org/ref/3.3.9/maven-core/lifecycles.html
POM 中可以指定以下配置:
具体的配置可以参考fastjson 的配置:
https://github.com/alibaba/fastjson/blob/master/pom.xml
如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合
1.聚合配置代码
<modules>
<module>模块一</module>
<module>模块二</module>
<module>模块三</module>
</modules>
例如:对项目的Hello、HelloFriend、MakeFriends这三个模块进行聚合
<modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriends</module>
</modules>
其中module的路径为相对路径。
继承为了消除重复的配置,我们把很多相同的配置提取出来,例如:grouptId,version,相同的依赖包等。
继承配置代码:
<parent>
<groupId>me.gacl.maven</groupId>
<artifactId>ParentProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../ParentProject/pom.xml</relativePath>
</parent>
Idea 中可以新建一个maven项目,然后删光文件夹,只留一个pom.xml,然后添加模块,选择继承。
profile
,它主要是为了解决不同环境所需的不同变量、配置等问题。比如我们内网开发的数据库配置,端口配置等是和生产环境不同的,这个时候就需要区分。<profiles>
<profile>
<!--不同环境Profile的唯一id-->
<!--开发环境-->
<id>dev</id>
<properties>
<!--profiles.active是自定义的字段(名字随便起),自定义字段可以有多个-->
<profiles.active>dev</profiles.active>
</properties>
</profile>
<profile>
<!--线上环境-->
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
Idea 中会显示配置的两个profile ,可以选择激活
pom文件里的配置为
<build>
<resources>
<resource>
<directory>src/main/resources/</directory>
<!--先排除掉两个文件夹-->
<excludes>
<exclude>dev/*</exclude>
<exclude>prod/*</exclude>
</excludes>
<includes>
<!--如果有其他定义通用文件,需要包含进来-->
<!--<include>messages/*</include>-->
</includes>
</resource>
<resource>
<!--这里是关键!根据不同的环境,把对应文件夹里的配置文件打包-->
<directory>src/main/resources/${profiles.active}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<!--不同环境Profile的唯一id-->
<!--开发环境-->
<id>dev</id>
<properties>
<!--profiles.active是自定义的字段(名字随便起),自定义字段可以有多个-->
<profiles.active>dev</profiles.active>
</properties>
</profile>
<profile>
<!--线上环境-->
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>
常用插件:
maven-antrun-plugin
maven-archetype-plugin
maven-assembly-plugin
maven-dependency-plugin
maven-enforcer-plugin
maven-help-plugin
maven-release-plugin
maven-resources-plugin
maven-surefire-plugin
build-helper-maven-plugin
exec-maven-plugin
jetty-maven-plugin
versions-maven-plugin
${basedir}表示项目根目录,即包含pom.xml文件的目录;
${version}表示项目版本;
${project.basedir}同${basedir};
${project.baseUri}表示项目文件地址;
${maven.build.timestamp}表示项目构件开始时间;
${maven.build.timestamp.format}表示属性${maven.build.timestamp}的展示格式,默认值为yyyyMMdd-HHmm,可自定义其格式,其类型可参考java.text.SimpleDateFormat。
${project.build.directory}表示主源码路径;
${project.build.sourceEncoding}表示主源码的编码格式;
${project.build.sourceDirectory}表示主源码路径;
${project.build.finalName}表示输出文件名称;
${project.version}表示项目版本,与${version}相同;
${project.xxx} 当前pom文件的任意节点的内容
${env.xxx} 获取系统环境变量。
${settings.xxx} 指代了settings.xml中对应元素的值。
1.统一版本
使用dependencyManagement 进行版本锁定,dependencyManagement可以统一管理项目的版本号,确保应用的各个项目的依赖和版本一致。
如果我们项目中只想使用spring core 5.2.0的包,pom.xml可以改为如下
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
</dependencies>
2.排除依赖
依赖查找的两个原则:
使用路径近者优先原则:直接依赖级别高于传递依赖。
使用第一声明者优先原则:谁先定义的就用谁的传递依赖,即在pom.xml文件自上而下,先声明的jar坐标,就先引用该jar的传递依赖。
Idea 可以安装maven helper插件,解决冲突。
maven helper插件安装成功,点开pom.xml会发现多了一个Dependency Analyzer视图,如下上面按钮的图标含义如下
上图说明有3个jar存在冲突,点击冲突的jar,可以查看和哪个jar产生冲突,如下图
点开pom.xml,切换到Dependency Analyzer视图,选择All Dependencies as Tree,点击要排除的jar,右键会出现Execlude选项,如下
Maven是开发中常用的工具,很重要,所以尽可能的掌握。
原创打字不容易,点赞,转发,关注三连,关注我公众号:【香菜聊游戏】有更多福利
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。