Maven 主要功能 Maven 是专门用于管理和构建 Java 项目的工具,它的主要功能有:
提供了一套标准化的项目结构
提供了一套标准化的构建流程(编译,测试,打包,发布…)
提供了一套依赖管理机制
标准化的项目结构 不同 IDE 之间,项目结构不一样,不通用
所有 IDE 使用 Maven 构建的项目结构完全一样,所有 IDE 创建的 Maven 项目都可以通用
Maven 的项目结构
标准化的构建流程 源代码⇒编译⇒测试⇒打包⇒发布,Maven 提供了一套简单的命令来完成项目构建
提供了一套依赖管理机制 比如 JDBC,需要使用的 MySQL 的驱动包,依赖管理其实就是管理你项目所依赖的第三方资源(Jar 包、依赖),原先我们是如何操作的呢:
下载 jar 包
将 jar 包复制到 lib 文件夹里
右键 jar 包,作为库
那 Maven 是如何管理依赖的呢
Maven 使用标准的 坐标 配置来管理各种依赖
只需要简单的配置就可以完成依赖管理
Maven 简介 Apache Maven 是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建、报告和文档
仓库分类
本地仓库
中央仓库:有 Maven 团队维护的全球唯一的仓库(免费的开源的 jar 包)
远程仓库(私服):一般有公司团队搭建的私有仓库(可以存放一下自己的公司的和一些可能具有版权的 jar 包)
查找流程:首先会查找本地仓库,如果本地仓库没有,则去中央仓库查找是否有,有的话就会 自动下载 到本地仓库
Maven 的安装和配置
解压即可安装
配置环境变量
下图中的 Maven 文件夹呢就是包含 bin 文件夹的文件夹
将 bin 目录添加到 Path 目录中
配置本地仓库:修改 conf/setting.xml 中的 <localRepository>
为其指定一个目录
注意:为了保守起见,在 Intellij 中也对 Maven 的本地路径配置一下:)
配置阿里云私服:修改 conf/setting.xml 中的 <mirrors>
标签,为其添加如下子标签
1 2 3 4 5 6 <mirror > <id > alimaven</id > <mirrorOf > central</mirrorOf > <name > aliyun maven</name > <url > http://maven.aliyun.com/nexus/content/groups/public/</url > </mirror >
Maven 的基本使用 Maven 的常用命令
compile:编译
clean:清理,删除前面编译产生的 target 目录
test:测试,执行 test 文件夹下的代码
package:打包
install:安装
在含有 pom.xml 文件的目录下,进入 PowerShell
1 2 3 4 5 mvn compile mvn clean mvn package mvn tast mvn install
Maven 的生命周期 Maven 对项目构建的生命周期划分为三套
clean:清理工作
default:核心工作,例如编译,测试,打包,安装等
site:产生报告,发布站点等
比如说执行 install,就会自动执行 compile,但是不会自动执行 clean(因为这是两套不同的生命周期)
依赖管理 使用坐标导入 jar 包
在 pom.xml 中编写 <dependencies>
标签
在 <dependencies>
标签中使用 <dependency>
来引入坐标
定义坐标的 groupId,artifactId,version
点击刷新按钮,是坐标生效(或者对 IDE 进行配置,每次变更自动生效)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <dependencies > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.32</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.12</version > </dependency > </dependencies >
比如去找 MySQL 的 Maven 配置信息(浏览器搜索 mysql maven
),比如从以下网页中找到了:MySQL Connector Java
还为我们提供了 maven 需要使用的信息
快速导入坐标信息到 pom.xml 如果本地仓库就有相应的 jar 包,那么直接可以通过搜索 jar 包的名字来导入(即可自动导入模板)
在 pom.xml 文件中,Alt+Insert
选择依赖项模板,自动为我们添加模板
依赖范围 通过设置坐标依赖范围(scope),可以设置对应 jar 包的作用范围:编译环境、测试环境、运行环境
编译环境:在主工程 java 文件夹中可以使用 测试环境:在测试文件夹 test 中可以使用 运行环境:
依赖范围的取值有以下六种,默认值是 compile(其实范围也是最大的)
分模块开发与设计 将原始模块按照功能拆分为若干个子模块,方便模块间的相互调用,接口共享
Intellij 中同时导入多个模块方式如下:
1、项目准备:之前做好的 SSM 整合的项目 maven_02_ssm 进行讲解 2、新建一个模块:maven_03_pojo
1)新建 com.itheima.domain 包 2)将 maven_02_ssm 中的 domain 下的 Book 实体类剪切至 maven_03_pojo 下的 domain 包下 3)此时 maven_02_ssm 将无法运行,因为缺少了 Book 实体类 4)现在要做到是:如何在 maven_02_ssm 中访问 / 加载 maven_03_pojo 下的 Book 实体类呢?
maven_03_pojo 模块中 pom.xml 的坐标如下
1 2 3 <groupId > com.itheima</groupId > <artifactId > maven_03_pojo</artifactId > <version > 1.0-SNAPSHOT</version >
那么我们在 maven_02_ssm 中引入上面的坐标
1 2 3 4 5 6 <dependency > <groupId > com.itheima</groupId > <artifactId > maven_03_pojo</artifactId > <version > 1.0-SNAPSHOT</version > </dependency >
此时就将 maven_03_pojo 模块引入进来了,此时 maven_02_ssm 也没有报错了
总结:将一个模块中的一部分功能抽取出来单独做一个模块,然后在原来的使用方去引用这个抽取出来的模块,这样就做成了两个模块
但是此时 02 模块会有问题?为什么呢 因为通过坐标导入,会将相应的资源下载到本地仓库,02 模块引入了 03 模块,但是本地仓库里面却找不到 03 的资源。因此,我们还需要将 03 模块 install 到本地仓库中
安装完之后,本地仓库中就可以找到模块 03 的资源了。此时我们在 compile 一下 02 模块,若能够编译成功,说明没有问题了
依赖管理 如果一个模块 A 依赖了模块 B,而 B 模块依赖了其他的东西,那么这个 A 模块可以直接使用这些东西
直接依赖:在当前项目中通过依赖配置建立的依赖关系 简介依赖:被依赖的资源如果依赖其他资源,当前项目简介依赖其他资源
依赖冲突
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
特殊优先:当同级配置类相同资源的不同版本,后配置的覆盖先配置的
可以通过此处查看项目中的依赖关系
可选依赖 比如说 02 模块引用了 04 模块,04 模块中引用了几个坐标。现在的需求是,我不想让 02 模块能够加载或引用 04 模块中的坐标,怎么处理呢?
那么在 04 模块中,对如下这个坐标进行处理
1 2 3 4 5 6 7 <dependency > <groupId > com.itheima</groupId > <artifactId > maven_03_pojo</artifactId > <version > 1.0-SNAPSHOT</version > <optional > true</optional > </dependency >
其实这个需要就是想要某个坐标没有传递性
排除依赖 比如引用了 maven_04_dao
坐标,但是排除这个坐标下的另外两个坐标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency> <groupId>com.itheima</groupId> <artifactId>maven_04_dao</artifactId> <version>1.0 -SNAPSHOT</version> <!--排除依赖是隐藏当前资源对应的依赖关系--> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </exclusion> </exclusions> </dependency>
那么可选和排除有什么区别呢:
用的可选,别人引用了我的坐标,但是不知道我背后引用了哪些坐标;对外隐藏当前所依赖的资源
用的排除,别人是知道我背后引用了那些坐标的;主动断开依赖的资源,被排除的资源无需指定版本
聚合
比如:上面的三个模块都是依赖 pojo 模块的,假如我们更新了 pojo 模块,上面三个模块会及时更新吗?如果 pojo 因为更新出现了问题,上面三个模块能够及时发现吗?
聚合:将多个模块组织成一个整理,同时进行项目构建的过程称为聚合(其实有点像事务的概念) 聚合工程:通常是一个不具有业务功能的 “空” 工程(仅有一个 pom 文件) 作用:使用聚合工程可以将多个模块编组,通过对聚合工程进行构建,实现对所包含的模块进行同步构建;当工程中某个模块发生更新时,必须保障工程中与已更新模块关联的模块同步更新,此时可以使用聚合工程来解决批量模块同步构建的问题
1)创建新 Maven 模块 2)聚合工程的特点:在 pom.xml 中,将打包方式设置为 pom
1 <packaging > pom</packaging >
3)设置管理模块的模块名称
1 2 3 4 5 6 7 8 <modules > <module > ../maven_02_ssm</module > <module > ../maven_03_pojo</module > <module > ../maven_04_dao</module > </modules >
4)进行同步编译 compile
继承 概念:继承描述的是两个工程间的关系,与 Java 中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
作用:简化配置;减少版本冲突
1)继承关系在子类中描述
1 2 3 4 5 6 7 <parent > <groupId > com.itheima</groupId > <artifactId > maven_01_parent</artifactId > <version > 1.0-RELEASE</version > <relativePath > ../maven_01_parent/pom.xml</relativePath > </parent >
此时,就可以继承父工程中依赖的坐标了
2)父工程中的坐标都必须要被所有子工程继承吗?不一定 可以在父工程 pom 文件中通过 dependencyManagement
来指定这是一个可选的坐标
1 2 3 4 5 6 7 8 9 10 11 <dependencyManagement > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > ${junit.version}</version > <scope > test</scope > </dependency > </dependencies > </dependencyManagement >
如果子工程中想要引用的话就在 pom 中加上相应的坐标,但是注意不要加版本号,因为他会自动继承父类中坐标的版本号;而对于其他子工程就不会自动继承引用这个坐标
1 2 3 4 5 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
3)子工程继承父工程中的坐标,只要父工程中坐标的版本号一改,所有子工程中对应的版本号都会改
聚合与继承的区别
作用
相同点
聚合与继承的 pom.xml 文件打包方式均为 pom,可以将两种关系制作到同一个 pom 文件中
聚合与继承均属于设计型模块,并无实际的模块内容
不同点
聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些
继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
属性
1)定义属性
1 2 3 4 <properties > <spring.version > 5.2.10.RELEASE</spring.version > </properties >
2)在定义坐标时,可以直接使用变量
1 2 3 4 5 6 7 8 9 10 11 <dependency > <groupId > org.springframework</groupId > <artifactId > spring-core</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency >
3)这样就好了呀,以后可以直接从这儿就可以看到各种坐标的版本
1 2 3 4 5 6 7 <properties > <spring.version > 5.2.10.RELEASE</spring.version > <junit.version > 4.12</junit.version > <mybatis-spring.version > 1.3.0</mybatis-spring.version > </properties >
版本管理 比如如下为某一工程 pom.xml 中的坐标,其中的 version 有什么用呢?
1 2 3 4 <groupId>com.itheima</groupId> <artifactId>maven_02_ssm</artifactId> <version>1.0 -SNAPSHOT</version> <packaging>war</packaging>
工程版本
SNAPSHOT(快照版本)
项目开发过程中临时输出的版本,称为快照版本
快照版本会随着开发的进展不断更新
RELESE(发布版本)
项目开发到进入阶段里程碑后,向团队外部发布较为稳定的版本,这种版本所对应的构建文件时稳定的,即便进行功能的后续开发,也不会改变当前发布版本的内容,这种版本称为发布版本
发布版本
多环境配置
maven 提供配置多种环境的设定,帮助开发者使用过程中快速切换环境
1)在父工程 pom.xml 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <profiles > <profile > <id > env_dep</id > <properties > <jdbc.url > jdbc:mysql://127.1.1.1:3306/ssm_db</jdbc.url > </properties > <activation > <activeByDefault > true</activeByDefault > </activation > </profile > <profile > <id > env_pro</id > <properties > <jdbc.url > jdbc:mysql://127.2.2.2:3306/ssm_db</jdbc.url > </properties > </profile > <profile > <id > env_test</id > <properties > <jdbc.url > jdbc:mysql://127.3.3.3:3306/ssm_db</jdbc.url > </properties > </profile > </profiles >
2)对工程进行 install,然后可以查看项目构建好的 war 包,双击 war 包,进入 WEB-INF 文件夹 ⇒ classes 文件夹 ⇒ jdbc.properties 文件,查看配置是否生效
如果要更换环境,可以将设置默认启动环境的那几行代码切换一下位置,比如切换到测试环境中,那么 install 后,默认就是测试环境的配置了
或者可以不用挪动那几行代码,直接使用 Maven 指令来表明我们将使用 env_dep
环境来进行 install,如下图所示
跳过测试 跳过测试:跳过所有测试 跳过测试:指定跳过某些内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <build > <plugins > <plugin > <artifactId > maven-surefire-plugin</artifactId > <version > 2.12.4</version > <configuration > <skipTests > false</skipTests > <excludes > <exclude > **/BookServiceTest.java</exclude > </excludes > </configuration > </plugin > </plugins > </build >