maven学习手册
Posted 野生java研究僧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了maven学习手册相关的知识,希望对你有一定的参考价值。
maven学习手册
- 1.maven简介
- 2.maven的安装和配置
- 3.maven实战
- 4.依赖管理
- 5.生命周期与插件
- 6.maven工程的聚合和继承
- 7.maven版本号管理
- 8.多环境开发配置
- 9.跳过测试
- 10.私服
- 11.maven插件实战
1.maven简介
1.1 传统项目的弊端
-
jar包不统一,jar包不兼容导致项目问题
-
工程升级维护过程操作繁琐
1.2 Maven是什么
maven作为一个构建工具,不仅能帮我们自动化构建,还能够抽象构建过程,提供构建任务实现;它跨平台,对外提供了一致的操作接口,这一切足以使它成为优秀的、流行的构建工具。
Maven不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了中央仓库,能帮我自动下载构件。
Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型POM(Project Object Model:项目对象模型)
Maven是由java语言开发,它管理的东西以面向对象的形式设计,将一个项目看成一个对象,这个对象就叫做POM.
2.maven的安装和配置
2.1 maven的安装
首先需要确认的是你已经成功安装JDK,接着去maven官网下载安装包即可。下载地址:https://maven.apache.org/download.cgi
然后选择自己想要的版本即可。下载完毕后解压到你想要解压的目录即可。
配置环境变量 MAVEN_HOME和path即可
输入mvn-v 如显示如下信息即可安装配置成功
maven目录结构
bin目录: 该目录包含了mvn运行的脚本,这些脚本用来配置java命令,准备好classpath和相关的Java系统属性,然后执行Java命令。
boot目录: 该目录只包含一个文件,该文件为plexus-classworlds-2.5.2.jar。plexus-classworlds是一个类加载器框架,相对于默认的java类加载器,它提供了更加丰富的语法以方便配置,Maven使用该框架加载自己的类库。
conf目录: 该目录包含了一个非常重要的文件settings.xml。直接修改该文件,就能在机器上全局地定制Maven的行为,一般情况下,我们更偏向于复制该文件至/.m2/目录下(表示用户目录),然后修改该文件,在用户范围定制Maven的行为。
lib目录: 该目录包含了所有Maven运行时需要的Java类库,Maven本身是分模块开发的,因此用户能看到诸如maven-core-3.0.jar、maven-model-3.0.jar之类的文件,此外这里还包含一些Maven用到的第三方依赖如commons-cli-1.2.jar、commons-lang-2.6.jar等等。
2.2 为阿里云设置代理仓库
为maven设置阿里云代理仓库
因为Maven的镜像默认是国外的网站,我们下载jar包时就会非常慢,所以我们配置一个国内的阿里云镜像。
打开解压Maven的conf目录下的settings.xml文件,在<mirrors></mirrors>
中添加如下mirror:
<mirror>
<id>aliMaven</id>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
配置JDK编译版本,防止在编辑器中运行时出现Java版本编译警告:
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
配置本地仓库目录
<localRepository>D:\\maven\\repository</localRepository>
2.3 maven常用命令简单说明
- mvn clean:表示运行清理操作(会默认把target文件夹中的数据清理)。
- mvn clean compile:表示先运行清理之后运行编译,会将代码编译到target文件夹中。
- mvn clean test:运行清理和测试。
- mvn clean package:运行清理和打包。
- mvn clean install:运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用。
- mvn clean deploy:运行清理和发布(发布到私服上面)。
3.maven实战
3.1 一个简单的maven项目
开始一个新的Maven项目,在命令行使用Maven Archetype插件。
mvn -B archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app
-DartifactId:项目名称
-DgroupId:公司组织名
命令执行成功就会得到这样一个简单的maven项目,使用idea打开查看项目目录结构
3.2 maven常用命令简单说明
- mvn clean:表示运行清理操作(会默认把target文件夹中的数据清理)。
- mvn clean compile:表示先运行清理之后运行编译,会将代码编译到target文件夹中。
- mvn clean test:运行清理和测试。
- mvn clean package:运行清理和打包。
- mvn clean install:运行清理和安装,会将打好的包安装到本地仓库中,以便其他的项目可以调用。
- mvn clean deploy:运行清理和发布(发布到私服上面)。
3.3 为这个简单的maven项目安装依赖
你会希望构建并打包这个应用。想要构建打包这个应用,在包含pom.xml的目录 下运行 mvn install
这个pom.xml文件是你将会面对的Maven项目中最基础的POM,一般来说一个 POM文件会复杂得多:定义多个依赖,自定义插件行为。最开始的几个元素 ——groupId,artifactId, packaging, version——是Maven的坐标(coordinates), 它们唯一标识了一个项目。name和url是POM提供的描述性元素,它们给人提供了可阅 读的名字,将一个项目关联到了项目web站点。最后,dependencies元素定义了一个 单独的,测试范围(test-scoped)依赖,依赖于称为JUnit的单元测试框架。这些话题 将会第 3.5 节 “核心概念”被深入介绍,当前,你所需知道的是,pom.xml是一个让 Maven跑起来的文件。 当Maven运行的时候,它是根据项目的pom.xml里设置的组合来运行的,一个最上级的 POM定义了Maven的安装目录,在这个目录中全局的默认值被定义了,(可能)还有一些 用户定义的设置。想要看这个“有效的 (effective)”POM,或者说Maven真正运行根据 的POM,在simple项目的基础目录下跑下面的命令。
mvn help:effective-pom
一旦你运行了此命令,你应该能看到一个大得多的POM,它暴露了Maven的默认设置
3.4 maven常见标签说明
代码的第一行是XML头,指定了该xml文档的版本和编码方式。 project是所有pom.xml的根元素,它还声明了一些POM相关的命名空间及xsd元素。 根元素下的第一个子元素modelVersion指定了当前的POM模型的版本,对于Maven3来说,它只能是4.0.0 代码中最重要是包含了groupId,artifactId和version了。这三个元素定义了一个项目基本的坐标,在Maven的世界,任何的jar、pom或者jar都是以基于这些基本的坐标进行区分的。
groupId 定义了项目属于哪个组,随意命名,比如谷歌公司的myapp项目,就取名为 com.google.myapp
artifactId 定义了当前Maven项目在组中唯一的ID,比如定义hello-world。
version 指定了项目当前的版本0.0.1-SNAPSHOT,SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的。
name 元素生命了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个POM声明name,以方便信息交流
description 表示一个项目的描述
4.依赖管理
4.1 依赖配置
依赖指当前项目运行所需的jar,一个项目可以设置多个依赖。
<!-当前项目所依赖的所有jar-->
<dependencies>
<!-设置具体的依赖-->
<dependency>
<!-依赖所属群组id-->
<groupId>junit</groupId>
<!-依赖所属项目id-->
<artifactId>junit</artifactId>
<!-依赖版本号-->
<version>4.12</version>
</dependency>
</dependencies>
根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:
- grounpId、artifactId和version:以来的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖。
- type:依赖的类型,对于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值为jar
- scope:依赖的范围
- optional:标记依赖是否可选
- exclusions:用来排除传递性依赖
4.2 依赖范围
依赖范围就是用来控制依赖和三种classpath(编译classpath,测试classpath、运行classpath)的关系,Maven有如下几种依赖范围:
- **compile:**编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。典型的例子是spring-code,在编译、测试和运行的时候都需要使用该依赖。
- test: 测试依赖范围。使用次依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此依赖。典型的例子是Jnuit,它只有在编译测试代码及运行测试的时候才需要。
- **provided:**已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时候无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器以及提供,就不需要Maven重复地引入一遍。
- **runtime:**运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
- **system:**系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致,但是,使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能构成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量,如:
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<Version>2.0</Version>
<scope>system</scope>
<systemPath>$java.home/lib/rt.jar</systemPath>
</dependency>
4.3 依赖传递
依赖具有传递性,分两种
(1)直接依赖:在当前项目中通过依赖配置建立的依赖关系
(2)间接依赖:被依赖的资源如果依赖其他资源,则表明当前项目间接依赖其他资源
以一个项目为根,直接依赖称为1度资源,直接依赖的直接依赖称为2度资源,直接依赖的直接依赖的直接依赖称为3度资源。
4.4 依赖传递的冲突问题
在依赖传递过程中产生了冲突,我们有三种优先法则
(1)路径优先:当依赖中出现相同资源时,层级越深,优先级越低,反之则越高
(2)声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖靠后的
(3)特殊优先:当同级配置了相同资源的不同版本时,后配置的覆盖先配置的
4.5 可选依赖
选依赖指的是对外隐藏当前所依赖的资源➡不透明 ,加一个<optional>
标签 ,optional中的值设置为true即可
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
<!-- 此依赖只在当前项目中使用,不对外传递-->
<optional>true</optional>
</dependency>
4.6 排除依赖
排除依赖指主动断开间接依赖的资源,被排除的资源无需指定版本一一不需要。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
<exclusions>
<!-- 排除依赖 spring-context-->
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
5.生命周期与插件
5.1 生命周期
Maven构建生命周期描述的是一次构建过程经历经历了多少个事件。
Maven对项目构建的生命周期划分为3个阶段。
- clean生命周期:清理工作。
- default生命周期:核心工作,例如编译,测试,打包,部署等。
- site生命周期:产生报告,发布站点等。
Maven有三个内置的构建生命周期(build lifecycle),它们彼此独立,分别是:clean、default、site。clean生命周期主要负责项目的清理工作,default生命周期主要负责项目的部署工作,site生命周期主要负责创建项目的web站点。我们平常用的maven命令mvn clean package中的clean属于clean生命周期,package属于default生命周期。
每个生命周期都有一些列不同的构建阶段(build phase,也叫build stage)组成。生命周期内的这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。比如clean生命周期有pre-clean、clean、post-clean三个阶段,当我们执行mvn clean的时候其实相当于执行了mvn pre-clean clean,clean前面的阶段都会被执行。
生命周期及其包含的阶段如下:
Clean生命周期:
阶段(phase) | 说明 |
---|---|
pre-clean | 执行清理前的预处理工作 |
clean | 清理之前构建的结果 |
post-clean | 执行清理后需要做的工作 |
default生命周期:
阶段(phase) | 说明 |
---|---|
validate | 验证项目有效性还有所有必要的信息是否可以获取到 |
initialize | 初始化构建状态,比如设置一些属性或者创建一些目录 |
generate-sources | 生成一些源码,这些源码在编译的时候可能会用到 |
process-sources | 处理源码,比如过滤一些值 |
generate-resources | 生成一些资源,在打包的时候可能会包含这些资源 |
process-resources | 拷贝或者处理资源,将它们移动到目标目录,用于打包 |
compile | 编译项目的源码 |
process-classes | 后置处理编译阶段生成的文件,比如对Java类进行字节码增强 |
generate-test-sources | 生成一些测试源码,在编译的时候可能会用到 |
process-test-sources | 处理测试源码,比如过滤一些值 |
generate-test-resources | 创建测试需要用的资源 |
process-test-resources | 拷贝或者处理资源,将它们移动到测试用的目录 |
test-compile | 编译测试源码,结果输出到目标目录 |
process-test-classes | 后置处理测试阶段编译产生的文件,比如对Java类进行字节码增强 |
test | 使用合适的单元测试框架进行测试,这些测试不应该依赖被打包或部署的代码 |
prepare-package | 在真正打包前做一些必要的准备操作,这个操作会产生未打包的,处理过的package版本 |
package | 将编译后的代码打包成可分发的格式,比如jar包 |
pre-integration-test | 执行集成测试之前的准备工作,比如设置一些需要的环境信息 |
integration-test | 如果有必要,会处理和部署包到继承测试可以运行的环境中 |
post-integration-test | 集成测试后的后置处理,比如清理集成测试用的环境 |
verify | 运行检测任务,以检查包是否合法,是否符合质量要求 |
install | 将包安装到本地仓库,作为依赖提供给本地的其它项目用 |
deploy | 将包发送到远程仓库,其它的开发者和项目可以使用它作为依赖 |
site生命周期:
阶段(phase) | 说明 |
---|---|
pre-site | 执行生成项目站点前的准备工作 |
site | 生成项目站点文档 |
post-site | 执行操作用于完成站点文档生成,为站点部署做准备 |
site-deploy | 部署站点文档到指定的web服务器 |
5.2 插件
生命周期中的阶段,类似java的模版方法,它是抽象的,需要由插件去实现它。执行maven命令的时候都是由各个生命周期阶段的插件来完成具体的工作的。比如default生命周期的package阶段可能就是由maven-jar-plugin完成的,之所以说是可能,是因为maven会给一些阶段绑定默认的插件实现,我们也可以通过提供别的插件来改变阶段的执行。
插件除了和生命周期的阶段绑定执行,也可以单独执行,比如mvn dependency:tree可以直接执行dependency插件的tree目标。即生命周期离不开插件,但是插件却可以离开生命周期单独执行。
Maven的核心是一个插件执行框架; 所有的工作都是通过插件完成的。寻找一个特定的目标来执行?有构建和报告插件:构建期间将执行
构建插件,并且应在POM 的元素中配置它们。
报告插件将在站点生成期间执行,并且应在POM 的元素中进行配置。由于Reporting插件的结果是生成的站点的一部分,因此Reporting插件应该是国际化的和本地化的。
在项目的POM文件中配置插件,
添加标签,在标签内添加,在标签内添加,最后在内指定插件的属性,包括groupId,artifactId,version,configuration等属性
更多插件的使用方式请查看maven官方插件 https://maven.apache.org/plugins/index.html
6.maven工程的聚合和继承
6.1 maven工程聚合描述
项目拆分成多个模块之后,各模块之间相互依赖,并发布到本地仓库中。
聚合用于快速构建maven工程,一次性构建多个项目/模块。
创建一个新的maven工程,然后里面src等东西删除掉,只留下pom文件和项目配置文件
pom配置为:
<packaging>pom</packaging>
然后在这个新建的maven工程里面,新建所需要的子模块即可
假设我们现在是这样一个结构的项目,依次从右至左进行依赖,然后我们每次更改代码,都有install,然后刷新maven,更改的代码才会生效,我们如果做成聚合的就不一样了,我只需要更新一个总的pom,其余的子模块会根据他们的依赖关系依次进行更新
我们现在改变项目目录结构,采用聚合的方式,项目结构如图所示:他们之间的依赖关系不变,但是他们都共同属于father工程的子模块,当father执行maven生命周期指令的时候,会根据依赖关系依次执行子模块的生命周期指令
项目结构图:
点击idea右侧maven工具栏,可以看到father模块变成了root项目
6.2 ssm项目聚合maven工程示例
1.新建一个总的工程 compassFather
pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.compass.example</groupId>
<artifactId>com.compass.father</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>compassDao</module>
<module>compassBean</module>
<module>compassService</module>
<module>compassController</module>
</modules>
</project>
2.新建一个实体模块
pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.compass.example</groupId>
<artifactId>com.compass.bean</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.新建一个模块dao
pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.compass.example</groupId>
<artifactId>com.compass.dao</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- spring依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.compass.example</groupId>
<artifactId>com.compass.bean</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- springJDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- mybatis整合其他框架的依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!-- mysql驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 德鲁伊连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependencyMaven速查手册