Maven基础学习笔记
Maven
1.安装maven
1.下载maven仓库
maven的下载地址 选择windows的版本
2.配置maven的环境变量
先下载jdk并配置jdk的环境,因为maven是依赖于java的
配置完后,编辑用户变量path
3.配置maven的镜像
打开在conf/setting.xml
修改文件内容
<localRepository>D:\maven\apache-maven-3.8.4\maven_repository</localRepository>
# 阿里云镜像
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>
http://maven.aliyun.com/nexus/content/groups/public/
</url>
<mirrorOf>central</mirrorOf>
</mirror>
在安装的目录下建立一个文件夹为maven_repository
配置完毕
2.maven的命令行
1.maven核心概念:坐标
maven中的坐标来唯一定位一个jar包的位置
groupid
:公司或组织的idartifactid
:一个项目或者项目中的一个模板的idversion
:版本号
坐标和仓库中的jar包的存储路径之间的对应关系
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
Maven本地仓库根目录\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar
这里的仓库就是一开始自己配置的仓库位置
2.实验操作
1.创建工作目录作为后面操作的工作空间
D:\idea_code\maven
这个时候我们已经有了三个核心目录
maven核心程序
maven本地仓库
本地工作空间
2.在工作空间目录下打开命令行
3.使用命令生成maven工程
mvn archetype:generate
后面就会有一系列的配置
这个就相当于是脚手架的作用,这其中会直接有junit
的依赖
有时候对应的依赖下会有<scope></scope>
的标签,这个是配置依赖的范围
2.maven核心概念:pom
1.含义
POM:Project Object Model
,项目对象模型。
2.对应的配置文件
POM 理念集中体现在 Maven 工程根目录下 pom.xml 这个配置文件中。所以这个 pom.xml 配置文件就是 Maven 工程的核心配置文件。其实学习 Maven 就是学这个文件怎么配置,各个配置有什么用。
<project>
表示对当前工程进行配置和管理<modelversion>
从maven2开始就是固定的4.0.0<packaging>
表示的是依赖打包的文件类型<properties>
配置对应的配置信息<project.build.sourceEncoding>
工程构建过程中读取源码时使用的字符集,这个是在<properties>
中<dependencies>
3.maven核心概念:约定的目录结构
java
下面还必须要有com
的组编号和resources
和test
都是maven的约定目录结构,在maven的项目中约定大于配置,配置大于编码
4.执行maven的构建命令
这些都是在cmd中执行的,这些命令都是直接可以输入的,还可以组合指令
1.要求
运行Maven中和构建操作相关的命令时,必须进入到pom.xml所在的目录。如果没有在pom.xml所在的目录运行Maven的构建命令,那么会看到下面的错误信息:
The goal you specified requires a project to execute but there is no POM in this directory
注意: 这里的mvn -v是查看maven的版本号
mvn -v 命令和构建操作无关,只要正确配置了 PATH,在任何目录下执行都可以。而构建相关的命令要在 pom.xml 所在目录下运行——操作哪个工程,就进入这个工程的 pom.xml 目录。
2.清理操作
mvn clean
删除target目录
3.编译操作
-
mvn compile
主程序编译 -
mvn test-compile
测试程序编译 -
target/class
主体程序编译结果存放的目录 -
target/test-classes
测试程序编译结果存放的目录
4.测试操作
-
mvn test
-
测试的报告存放的目录
target/surefire-reports
5.打包操作
mvn package
target
打包的结果——jar 包,存放的目录 只存储主程序文件
6.安装操作
mvn install
安装的效果是将本地构建过程中生成的 jar 包存入 Maven 本地仓库。这个 jar 包在 Maven 仓库中的路径是根据它的坐标生成的。另外,安装操作还会将 pom.xml 文件转换为 XXX.pom 文件一起存入本地仓库。所以我们在 Maven 的本地仓库中想看一个 jar 包原始的 pom.xml 文件时,查看对应 XXX.pom 文件即可,它们是名字发生了改变,本质上是同一个文件。
5.创建maven的web工程
1.说明
使用mvn archetype:generate
命令生成web工程,需要使用一个专用的archetype
.
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
这个是固定的操作,参数 archetypeGroupId、archetypeArtifactId、archetypeVersion(这些是之前配置了的) 用来指定现在使用的 maven-archetype-webapp 的坐标。
2.操作
使用上面的命令就可以创建一个web项目,但是注意,不要在上一个maven的项目下建立一个新的web的maven项目,要回到工作目录的根目录,接下来就是和上面的操作相同了
3.生成的pom.xml
注意这里的默认打包方式是war
<packaging>war</packaging>
4.生成的web工程的目录结构
在webapp
的目录下有index.jsp,WEB-INF
目录下有web.xml
5.接下来就是jsp的配置操作了,正常操作
6.注意这里可能会出现错误
程序包 javax.servlet.http 不存在 程序包 javax.servlet 不存在 找不到符号 符号: 类 HttpServlet
出现这些错误的话,就是缺少一个jar的依赖,要到maven仓库 下载依赖servlet-api.jar
对于这个jar的配置就是在pom.xml中使用<dependency></dependency>
来进行导入jar包,之后重新执行mvn compile
命令进行编译
7.将war包部署到Tomcat上运行
将war包复制到Tomcat/webapps
中,启动tomcat
startup.bat
进行启动tomcat,tomcat会自动解压war包,形成对应的文件夹
6.让web工程依赖java工程
1.观念
明确一个意识:从来只有 Web 工程依赖 Java 工程,没有反过来 Java 工程依赖 Web 工程。本质上来说,Web 工程依赖的 Java 工程其实就是 Web 工程里导入的 jar 包。最终 Java 工程会变成 jar 包,放在 Web 工程的 WEB-INF/lib 目录下。
2.操作
在对应的pom.xml文件中使用<dependency></dependency>
来引入第一个实验的jar包,坐标指定
3.在web工程中,编写测试代码
- 补充创建目录 就是补全之前在test中的目录结构,这里还要恢复出之前第一个项目的环境文件夹
- 确定web工程是否导入了junit的jar包
- 创建测试类 将第一个实验的java的程序包拷贝到这个目录中,这里的目录结构和package的目录结构一样
4.执行maven命令
-
测试命令
mvn test
说明:测试操作中会提前自动执行编译操作,测试成功就说明编译也是成功的。 -
打包命令
mvn package
通过查看 war 包内的结构,我们看到被 Web 工程依赖的 Java 工程确实是会变成 Web 工程的 WEB-INF/lib 目录下的 jar 包。 -
查看maven项目所使用的依赖
mvn dependency:list
来展示出依赖的文件 格式:groupId:artifactId:打包方式:version:依赖的范围
这里的格式就是xml中的坐标配置 -
查看maven项目使用树形来展示
mvn dependency:tree
然后基于依赖的传递性
7.测试依赖的范围
1.依赖范围
- 标签的范围:
dependencies/dependency/scope
- 标签的可选值:
compile/test/provided/system/runtime/import
compile是默认的依赖有效范围
main目录(空间) test目录(空间) 开发时间(时间) 部署到服务器(时间)
compile 有效 有效 有效 有效
test 无效 有效 有效 无效
main目录(空间) test目录(空间) 开发时间(时间) 部署到服务器(时间)
compile 有效 有效 有效 有效
provided 有效 有效 有效 无效
compile:通常使用的第三方框架的jar包这样在项目实际运行时真正要用到的jar包都是以compile范围进行依赖的。比如SSM框架所需jar包。
test:测试过程中使用的jar包,以test范围依赖进来。比如junit。,
provided:在开发过程中需要用到的"服务器上的jar包"通常以provided范围依赖进来。比如servlet-api、jsp-api。而这个范围的jar包之所以不参与部署、不放进war包,就是避免和服务器上已有的同类jr包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上己经有了,你就别带啦!
8.测试依赖的传递性
1.依赖的传递性
- 概念 :
A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?
- 传递的原则 :
在 A 依赖 B,B 依赖 C 的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围.
- B依赖C时使用compile范围:可以传递
- B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。
9.测试依赖的排除
1.概念
当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这种情况都是为了避免 jar 包之间的冲突。所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
2.配置方式
<dependency>
<groupId>com.atguigu.maven</groupId>
<artifactId>pro01-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
<!-- 使用excludes标签配置依赖的排除 -->
<exclusions>
<!-- 在exclude标签中配置一个具体的排除 -->
<exclusion>
<!-- 指定要排除的依赖的坐标(不需要写version) -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
通过<exclusions></exclusions>
来配置排除包信息来避免jar的冲突
10.继承
1.概念
maven工程之间,A工程继承B工程
- B工程:父工程
- A工程:子工程
本质上是A工程的pom.xml中的配置继承了B工程中的pom.xml的配置
2.作用
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
它的背景是:
- 对一个比较大型的项目进行了模块拆分。
- 一个 project 下面,创建了很多个 module。
- 每一个 module 都需要配置自己的依赖信息。
它背后的需求是:
- 在每一个 module 中各自维护各自的依赖信息很容易发生出入,不易统一管理。
- 使用同一个框架内的不同 jar 包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统一。
- 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将以往的经验沉淀下来,节约时间和精力。
3.举例
使用 Spring 时要求所有 Spring 自己的 jar 包版本必须一致。为了能够对这些 jar 包的版本进行统一管理,我们使用继承这个机制,将所有版本信息统一在父工程中进行管理。
4.操作
- 创建父工程
创建过程和前面创建一个maven项目是一样的操作,注意这里要修改他的打包方式:
<packaging>pom</packaging>
只有打包方式为 pom 的 Maven 工程能够管理其他 Maven 工程。打包方式为 pom 的 Maven 工程中不写业务代码,它是专门管理其他 Maven 工程的工程。
- 创建模块工程
进入父工程,创建子工程,使用命令mvn archetype:generate
来创建模块项目
- 查看被添加新内容的父工程的pom.xml
<modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
- 查看子工程的pom.xml
<!-- 使用parent标签指定当前工程的父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- 子工程的坐标 -->
<!-- 如果子工程坐标中的groupId和version与父工程一致,那么可以省略 -->
<!-- <groupId>com.atguigu.maven</groupId> -->
<artifactId>pro04-maven-module</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
- 在父工程中实现依赖的统一管理
使用<dependencyManageMent></dependencyManageMent>
来实现对依赖的管理,这些被刮管理的依赖并没用被真正的引入到工程中,<groupId><artifactId><version>
包含在其中
- 子工程中引用那些被父工程管理的依赖
关键点就是省略版本号,并且可以实现有选择地选择依赖,把版本号去掉就表示子工程中这个依赖的版本由父工程决定。
-
在父工程中升级依赖信息的版本号
-
在父工程中声明自定义的属性
<!-- 通过自定义属性,统一指定Spring的版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 自定义标签,维护Spring版本数据 -->
<feng.spring.version>4.3.6.RELEASE</feng.spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${feng.spring.version}</version>
</dependency>
通过继承就可以实现成熟的版本号进行传递,减少时间
11.聚合
这个是在前面的工程完整后,进行的操作
1.简介
使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目。
- 项目:整体
- 模块:部分
从继承关系角度来看:
- 父工程
- 子工程
从聚合关系角度来看:
- 总工程
- 模块工程
2.好处
- 一键执行 Maven 命令:很多构建命令都可以在“总工程”中一键执行。
以 mvn install 命令为例:Maven 要求有父工程时先安装父工程;有依赖的工程时,先安装被依赖的工程。我们自己考虑这些规则会很麻烦。但是工程聚合之后,在总工程执行 mvn install 可以一键完成安装,而且会自动按照正确的顺序执行。
- 配置聚合之后,各个模块工程会在总工程中展示一个列表,让项目中的各个模块一目了然。
3.聚合的配置
在总工程中配置modules
即可
<modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
4.依赖循环问题
如果 A 工程依赖 B 工程,B 工程依赖 C 工程,C 工程又反过来依赖 A 工程,那么在执行构建操作时会报下面的错误: 这个操作要避免
DANGER
[ERROR] [ERROR] The projects in the reactor contain a cyclic reference:
这个的错误是循环引用
3.其他核心信息
1.生命周期
1.作用
为了让构建过程自动化完成,Maven 设定了三个生命周期,生命周期中的每一个环节对应构建过程中的一个操作。
2.三个生命周期
-
clean 清理操作相关的 pre-clean clean post-clean
-
site 生成站点相关的 pre-site site post-site deploy-site
-
default 主要构建过程 按顺序构建
-
validate
-
generate-sources
-
process-sources
-
generate-resources
-
process-resources 复制并处理资源文件,至目标目录,准备打包
-
compile 编译项目 main 目录下的源代码
-
process-classes
-
generate-test-sources
-
process-test-resources 复制并处理资源文件,至目标测试目录。
-
test-compile 编译测试源代码。
-
process-test-classes
-
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
-
prepare-package
-
package 接受编译好的代码,打包成可发布的格式,如JAR。
-
pre-integration-test
-
integration-test
-
post-integration-test
-
verify
-
install将包安装至本地仓库,以让其它项目依赖。
-
deploy将最终的包复制到远程的仓库,以让其它开发人员共享;或者部署到服务器上运行(需借助插件,例如:cargo)。
-
特点
- 前面三个生命周期彼此是独立的。
- 在任何一个生命周期内部,执行任何一个具体环节的操作,都是从本周期最初的位置开始执行,直到指定的地方。(本节记住这句话就行了,其他的都不需要记)
Maven 之所以这么设计其实就是为了提高构建过程的自动化程度:让使用者只关心最终要干的即可,过程中的各个环节是自动执行的。
3.插件和目标
- 插件
Maven 的核心程序仅仅负责宏观调度,不做具体工作。具体工作都是由 Maven 插件完成的。
- 目标
一个插件可以对应多个目标,而每一个目标都和生命周期中的某一个环节对应。