不会Maven?读完这篇就够了!
Posted 四点钟程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不会Maven?读完这篇就够了!相关的知识,希望对你有一定的参考价值。
先上学习图谱!
Maven概览
为什么使用Maven?
目前问题:
1. jar包混乱:工程中存在jar包重复,版本不一致的情况.
2. 添加jar包随意:需要用到第三方jar时,随便下载就添加到项目中了,没有记录
3. 重复构建:每个开发人员从svn下载完代码后,都要对项目进行配置,构建.
4. 不同环境的构建差异:总是存在在开发环境运行良好的程序,到了测试环境编译不通过,或者不同环境的配置文件不一致,需要手动的去修改
5. 模块间的开发依赖纯手动处理:提倡模块化的开发,可是怎么做好模块化开发之间的依赖处理,没有解决方案。
Maven介绍
maven是什么?
Maven是一个项目管理和综合工具。Maven提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。
在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建报表,检查,构建和测试自动化设置。
Maven能干什么?
项目构建
依赖管理
仓库管理
web项目与自动化部署
聚合和继承。。等
maven的优点:
1.对第三方依赖库进行统一的版本管理。
2.统一项目的目录结构。
3.统一软件构建阶段
4.支持多种插件
5.自动生成项目网站和报表
Maven下载
目录结构:
bin:maven的运行脚本,mvn.cmd是基于Windows的脚本。在CMD中每次输入一条MVN的命令都是在调用并执行这些脚本。
boot:该目录只有一个文件plexus-classworlds-2.5.2.jar。它是一个类加载器的框架,相对于JDK中的类加载器,它提供了更丰富的语法以方便配置,maven使用该框架加载自己的类库。
conf:该目录包含了一个非常重要的文件settings.xml。配置该文件就能在Project中定制maven的行为。
lib:包含了所有的maven运行需要的java类库以及用到的第三方类库。
Maven环境变量配置
1. 下载apache-maven-3.5.0-bin.zip
2. 配置maven的环境变量
3. 执行mvn命令验证:mvn -v
注:Maven 3.3+ require JDK 1.7 or above to execute
Maven常用命令
创建java工程
mvn archetype:generate
-DgroupId 公司名
-DartifactId 项目名称
-DgroupId 公司名
-DarchetypeArtifactId 骨架
(指定ArchetypeId,maven-archetype-quickstart是java工程,maven-archetype-webapp是web工程)
-DinteractiveMode 是否使用交互模式
关于pom.xml
maven工程结构和内容定义在pom.xml中,全称即为project object moduel
----------------------------------------------------------
约定优于配置
maven使用约定而不是配置,意味着开发者不需要再自己创建构建过程。
当创建maven工程时,maven会创建默认的工程结构,开发者只需要合理的放置配置文件,而在pom.xml中无需做任何配置。
----------------------------------------------------------
src
-main
–bin 脚本库
–java java源代码文件
–resources 资源库,会自动复制到classes目录里
–filters 资源过滤文件
–assembly 组件的描述配置(如何打包)
–config 配置文件
–webapp web应用的目录。WEB-INF、css、js等
-test
–java 单元测试java源代码文件
–resources 测试需要用的资源库
–filters 测试资源过滤库
-site Site(一些文档)
target 存放当前编译后的源文件
LICENSE.txt Project’s license
README.txt Project’s readme
-----------------------------------------------------------
mvn compile 编译源代码
mvn clean 清空target
mvn package 打包
mvn install 安装输出文件到本地仓库
mvn clean package 先清除再打包
mvn jar:jar 打成jar包
mvn deploy 发布到远程仓库
mvn dependency:tree > d.txt maven依赖结构
mvn site
-----------------------------------------------------------
Maven坐标
maven坐标-maven构件
什么是maven构件?
在maven中,任何依赖(jar包),或者项目输出(自己打包的jar、war等)都可以成为构件。
每个构件都有自己的唯一标识(唯一坐标),由groupId,artifactId,version等信息构成。
groupId:一般代表公司名,或者组织名
artifactId:一般项目名称
version:当前项目的版本号
packaging:定义maven项目打包的方式,也可以打包成war等,当不定义packaging时,maven会默认值jar
Maven仓库
maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库。(仓库就是存放依赖和构件的地方)
maven的分类:1. 本地仓库 2. 远程仓库
在远程仓库中分成3类:1.中央仓库 2.私服 3.其他公共库。
1.本地仓库,顾名思义,就是Maven在本地存储构件的地方。注:maven的本地仓库,在安装maven后并不会创建,它是在第一次执行maven命令的时候才被创建
maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository的仓库目录,这就是maven仓库的默认位置。
如何更改maven默认的本地仓库的位置,需要修改setttings.xml文件中localRepository标签
用户范围修改 把settings.xml放到.m2文件下
全局修改 maven目录conf中settings.xml
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
Maven生命周期
maven有三套相互独立的生命周期,一般的容易将maven的生命周期看成一个整体,其实不然,这三套生命周期分别是:
Clean Lifecycle 在进行真正的构建之前进行一些清理工作
Default Lifecycle 构建的核心部分,编译、测试、打包、部署等。
Site Lifecycle 生成项目报告,站点,发布站点。
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个的clean是Clean生命周期的一个阶段。
运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install的时候,代码会被编译,测试,打包。
一、maven的生命周期
maven的生命周期就是对所有的构建过程进行抽象和统一。包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。
二、3套生命周期
maven有三套独立的生命周期,分别是clean,default,site。每个生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖前面的阶段。
1.clean生命周期:清理项目,包含三个phase
(1.1)pre-clean:执行清理前需要完成的工作
(1.2)clean:清理上一次构建生成的文件
(1.3)post-clean:执行清理后需要完成的工作。
2.default生命周期:构建项目,重要的phase:
(2.1)validate:验证工程是否正确,所有需要的资源是否可用
(2.2)compile:编译项目的源代码
(2.3)test:使用合适的单元测试框架来测试已编译的源代码,这些测试不需要已打包和部署。
(2.4)package:把已编译的代码打包成可发布的格式,比如jar。
(2.5)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用
(2.4)deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
3. site生命周期:建立和发布项目站点
(3.1)pre-site:生成项目站点之前需要完成的工作
(3.2)site:生成项目站点文档
(3.3)post-site:生成项目站点之后需要完成的工作
(3.4)site-deploy:将项目站点发布到服务器
三、命令行和生命周期
各个生命周期相互独立,一个生命周期的阶段前后依赖。
pom.xml详解
parent 集成,父模板的坐标
distributionManagement 负责管理构件发布配置
version 定义规则:
snapshot 快照
alpha 内侧
beta 公测
release 稳定版本
GA 最稳定版本
。。。
maven会根据模块的版本号(pom文件中的version)中是否带有-SNAPSHOT来判断是快照版本还是正式版本。
快照能被覆盖,正式版不能被覆盖(当然仓库配置为redeploy是能被覆盖的,比较坑)。
定义版本规则的:
<主版本>.<次版本>.<增量版本>
比如说1.2.3,主版本是1,次版本是2,增量版本是3。
module 聚合和哪些模块
dependencies 依赖集合
dependencyManagement 用于定义共同的依赖jar包,用户其他项目集成时使用同一的版本jar包,子模块不需要指定版本号
name url 是生成站点信息时用到
properties 属性标签,是在maven编译的时候发挥作用,例如:UTF-8 默认编码为UTF-8
还可以指定一些数据库的连接信息
还可以自定义标签统一管理我的所有的jar版本号,${取值}
build 里面放的是插件
plugins 插件
intellij maven插件
maven配置
打开 -> File -> Settings -> Maven
Maven home dictionary:
User Settings file:
Local repository:
Maven特性
依赖
maven的依赖范围就是用来控制与编译、测试、运行三种classpath的关系。
maven有以下几种依赖范围:
1.compile的范围(默认)
当依赖的scope为compile的时候,那么当前这个依赖的包,会在编译的时候将这个依赖加入进来,并且在打包(mvn package)的时候也会将这个依赖加入进去。
意思就是:编译范围有效,在编译打包时都会存储进去
2.provided的范围
当依赖的scope为provided的时候,在编译测试有效,在执行(mvn package)进行打包成war包时不会加入,比如:servlet-api,因为servlet-api在tomca等容器中已经存在,如果在打包进去的话,那么包之间会冲突。
3.test的范围
当依赖的scope为test时,指的是在测试范围有效,在编译与打包的时候不会使用这个依赖。
4.runtime的范围
当依赖的scope为runtime的时候,在运行的时候才会有依赖,在编译的时候不会依赖
5.system(系统范围)
system范围依赖于provided类似,但是你必须显示的提供一个对于本地系统中JAR文件的路径,这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分,这样的构建应该是一直可用的,maven也不会在仓库中去寻找它,如果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素,注意该范围是不推荐使用的(你应该一直尽量去公共或者定制的maven仓库中引用依赖)
注:默认情况下的scope范围是compile
传递性
我们的依赖是有传递性的。
规则:
1.路径最近者优先,c->b->a
c依赖b,b依赖a,c会优先使用b的jar包
2.路径相同配置最前者优先,c->b, c->a
c依赖b,c依赖a,必须要看b、a在c中哪个先声明的,优先使用先声明的jar包。
传递依赖会产生一个问题,是什么?
如何解决这个问题?
在这里提一下gradle依赖,会依赖最新版本的jar。
如果在传递依赖的包中,想去除某个jar包
原因:
1.降低工程的依赖数量
2.解决jar包版本冲突(ClassNotFound)
问题:如何查找冲突的jar包?
选择性依赖
在依赖中用<optional>jar</optional>直接去除这种依赖传递的特性,也就是说,如果别的项目引用设置了此依赖的项目,这个commons-logging不会被依赖到,例如在项目A中配置commons-logging的依赖,如果项目B依赖项目A,则在B中不会依赖commons-logging了。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
排除依赖
如果第三方的jar包没有用<optional>去除依赖的传递性,那么我们可以在当前的项目中使用<exclusion>元素声明排除依赖。
例如:项目A中配置了spring-core的依赖,如果项目B需要引用项目A,但是同时又不需要commons-logging的包,这个时候可以使用
<exclusion>元素排除即可,这种用法可以解决包版本冲突的问题。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
小技巧:pom.xml 右击->Diagrams
聚合
一个项目往往由多个模块构成的,在进行构建时,针对每个模块都进行构建命令是一件非常繁琐又容易出错的事情,所以maven的聚合功能能够替我们完成进行一次构建命令完成全部模块的的构建。
maven的聚合功能可以通过一个父模块讲所有的要构建模块整合起来,将父模块的打包类型声明为POM,通过<modules>将各模块集中到父pom中。
<modules>
<module>test-service</module>
<module>test-facade</module>
<module>test-dao</module>
</modules>
继承
maven中继承的概念与面向对象的继承概念是一致的,通过继承消除重复编码的行为。在这里,我们也可以通过一个父模块来挖财父模块与子模块共用依赖的继承关系。父模块的POM文件声明与平常一样,提取公共地方,子模块需要继承父模块。
注:通过parent标签进行继承
另外:
1.子模块没有声明groupId和version,这两个属性继承至父模块。但如果子模块有不同与父模块的groupId、version,也可以指定。
2.不应该继承artifactId,如果groupId,version,artifactId完全继承的话会造成坐标冲突;另外即使使用不同的groupId或version,同样的artifactId也容易产生混淆。
3.使用继承后parent也必须像子模块一样加入到聚合模块中。
maven可继承的POM元素
groupId: 项目组ID,项目坐标的核心元素
version:项目版本
description:项目的描述信息
organization:项目的组织信息
inceptionYear: 项目的创建年份
develovers: 项目开发者信息
distributionManagement:项目的部署信息
properties:自定义的maven属性
build:组件
。。。。
推荐书籍
《Maven实战》PDF下载:https://pan.baidu.com/s/1boZ6k83
现在架构师很流行,想看看阿里的架构师是怎么样思考问题的吗?极客时间最近推出了阿里P9专家的架构专栏,如果你也对架构感兴趣,请扫描学习一下,原价¥99/50期,今天最后一天优惠价¥68!(扫我的码后台留言后可返现12元)
往期回顾
以上是关于不会Maven?读完这篇就够了!的主要内容,如果未能解决你的问题,请参考以下文章