这里写目录标题
Maven
Maven 作为依赖管理工具
- jar 包的规模 随着我们使用越来越多的框架,或者框架封装程度越来越高,项目中使用的jar包也越来越多。项目中, 一个模块里面用到上百个jar包是非常正常的。
- jar 包的来源
- 使用 Maven 后,依赖对应的 jar 包能够自动下载,方便、快捷又规范。
- jar 包之间的依赖关系
- 使用 Maven 则几乎不需要管理这些关系,极个别的地方调整一下即可,极大的减轻了我们的工作量。
Maven 作为构建管理工具
-
管理规模庞大的 jar 包,需要专门工具。
-
脱离 IDE 环境执行构建操作,需要专门工具。
什么是 Maven
-
Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。
-
Maven 的工作机制
根据坐标创建 Maven(java) 工程
-
Maven 核心概念:坐标
-
Maven中的坐标 [1]向量说明 使用三个『向量』在『Maven的仓库』中唯一的定位到一个『jar』包
-
groupId:公司或组织的 id
-
artifactId:一个项目或者是项目中的一个模块的 id
-
version:版本号
-
举例: groupId:com.atguigu.maven
artifactId:pro01-atguigu-maven
version:1.0-SNAPSHOT
- 坐标和仓库中 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
创建Maven工程具体操作
-
创建目录作为后面操作的工作空间 例如:D:\maven-workspace\spaceVideo
-
使用mvn archetype:generate命令生成Maven工程
-
下面根据提示操作
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7:【直接回车,使用默认值】
Define value for property ‘groupId’: com.atguigu.maven
Define value for property ‘artifactId’: pro01-maven-java
Define value for property ‘version’ 1.0-SNAPSHOT: :【直接回车,使用默认值】
Define value for property ‘package’ com.atguigu.maven: :【直接回车,使用默认值】
Confirm properties configuration: groupId: com.atguigu.maven artifactId: pro01-maven-java version: 1.0-SNAPSHOT package: com.atguigu.maven Y: :【直接回车,表示确认。如果前面有 输入错误,想要重新输入,则输入 N 再回车。】
-
调整
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wUJxG00T-1691415733445)(D:\Image\Java\Basic\Maven\Mavenxml文件调整.png)]
Maven核心概念:POM
- 含义 POM:Project Object Model,项目对象模型。和 POM 类似的是:DOM(Document Object Model),文档对象模型。它们都是模型化思想的具体体现。
- 模型化思想 POM 表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项 目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数 据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。
- 对应的配置文件 POM 理念集中体现在 Maven 工程根目录下 pom.xml 这个配置文件中。所以这个 pom.xml 配置文件就 是 Maven 工程的核心配置文件。其实学习 Maven 就是学这个文件怎么配置,各个配置有什么用。
Maven核心概念:约定的目录结构
-
约定目录结构的意义
Maven 为了让构建过程能够尽可能自动化完成,所以必须约定目录结构的作用。例如:Maven 执行编 译操作,必须先去 Java 源程序目录读取 Java 源代码,然后执行编译,最后把编译结果存放在 target 目 录。
-
约定大于配置
Maven 对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常 方便。如果每次创建 Maven 工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:约定大于配置,配置大于编码。
执行 Maven 的构建命令
运行 Maven 中和构建操作相关的命令时,必须使用cd操作命令进入到 pom.xml 所在的目录。如果没有在 pom.xml 所 在的目录运行 Maven 的构建命令,那么会看到下面的错误信息:
The goal you specified requires a project to execute but there is no POM in
this directory
清理操作
mvn clean
效果:删除 target 目录
编译操作
主程序编译:mvn compile
测试程序编译:mvn test-compile
主体程序编译结果存放的目录:target/classes
测试程序编译结果存放的目录:target/test-classes
测试操作
mvn test
测试的报告存放的目录:target/surefire-reports
打包操作
mvn package
打包的结果——jar 包,存放的目录:target
安装操作
mvn install
在 Maven 仓库中生成的路径如下:
D:\maven-repository\com\atguigu\maven\pro01-maven-java\1.0-SNAPSHOT\pro01-maven-java-1.0-SNAPSHOT.jar
根据坐标创建 Maven(Web) 工程
操作步骤
- 运行生成工程的命令
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -
DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
-
生成的pom.xml
确认打包的方式是war包形式
<packaging>war</packaging>
-
在main中创建java程序,在java目录下创建Servlet程序,在XML中注册Servlet。
-
配置Servlet-api依赖
对于不知道详细信息的依赖可以到https://mvnrepository.com/网站查询。使用关键词搜索,然后在搜 索结果列表中选择适合的使用。
-
将 war 包部署到 Tomcat 上运行
-
查看当前 Web 工程所依赖的 jar 包的列表
mvn dependency:list
以树形结构查看
mvn dependency:tree
测试依赖的范围
标签所在位置:scope标签中
<dependencies>/<dependency>/<scope>
标签的可选值:compile(默认值)/test/provided/system/runtime/import
compile:通常使用的第三方框架的 jar 包这样在项目实际运行时真正要用到的 jar 包都是以 compile 范 围进行依赖的。比如 SSM 框架所需jar包。 test:测试过程中使用的 jar 包,以 test 范围依赖进来。比如 junit。
provided:在开发过程中需要用到的“服务器上的 jar 包”通常以 provided 范围依赖进来。比如 servletapi、jsp-api。而这个范围的 jar 包之所以不参与部署、不放进 war 包,就是避免和服务器上已有的同类 jar 包产生冲突,同时减轻服务器的负担。说白了就是:“服务器上已经有了,你就别带啦!”
依赖的排除
当 A 依赖 B,B 依赖 C 而且 C 可以传递到 A 的时候,A 不想要 C,需要在 A 里面把 C 排除掉。而往往这 种情况都是为了避免 jar 包之间的冲突。
所以配置依赖的排除其实就是阻止某些 jar 包的传递。因为这样的 jar 包传递过来会和其他 jar 包冲突。
配置方式:在dependency标签中添加exclusions标签
<dependency>
<!-- 使用excludes标签配置依赖的排除 -->
<exclusions>
<!-- 在exclude标签中配置一个具体的排除 -->
<exclusion>
<!-- 指定要排除的依赖的坐标(不需要写version) -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
继承
-
概念 Maven工程之间,A 工程继承 B 工程
B 工程:父工程
A 工程:子工程
本质上是 A 工程的 pom.xml 中的配置继承了 B 工程中 pom.xml 的配置。
-
作用
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
它的背景是:
-
对一个比较大型的项目进行了模块拆分。
-
一个 project 下面,创建了很多个 module。
- 每一个 module 都需要配置自己的依赖信息。
它背后的需求是:
- 在每一个 module 中各自维护各自的依赖信息很容易发生出入,不易统一管理。
- 使用同一个框架内的不同 jar 包,它们应该是同一个版本,所以整个项目中使用的框架版本需要统 一。
- 使用框架时所需要的 jar 包组合(或者说依赖信息组合)需要经过长期摸索和反复调试,最终确定 一个可用组合。这个耗费很大精力总结出来的方案不应该在新的项目中重新摸索。
通过在父工程中为整个项目维护依赖信息的组合既保证了整个项目使用规范、准确的 jar 包;又能够将 以往的经验沉淀下来,节约时间和精力。
-
举例
在一个工程中依赖多个 Spring 的 jar 包
[INFO] +- org.springframework:spring-core:jar:4.0.0.RELEASE:compile
[INFO] | - commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.springframework:spring-beans:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-expression:jar:4.0.0.RELEASE:compile
[INFO] +- org.springframework:spring-aop:jar:4.0.0.RELEASE:compile
[INFO] | - aopalliance:aopalliance:jar:1.0:compile
使用 Spring 时要求所有 Spring 自己的 jar 包版本必须一致。为了能够对这些 jar 包的版本进行统一管 理,我们使用继承这个机制,将所有版本信息统一在父工程中进行管理。
操作
- 创建父工程
创建的过程和前面创建 pro01-maven-java 一样。 修改它的打包方式:
<groupId>com.atguigu.maven</groupId>
<artifactId>pro03-maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 当前工程作为父工程,它要去管理子工程,所以打包方式必须是 pom -->
<packaging>pom</packaging>
只有打包方式为 pom 的 Maven 工程能够管理其他 Maven 工程。打包方式为 pom 的 Maven 工程中不 写业务代码,它是专门管理其他 Maven 工程的工程。
-
创建模块工程
模块工程类似于 IDEA 中的 module,所以需要进入 pro01-maven-parent 工程的根目录,然后运行 mvn archetype:generate 命令来创建模块工程。
-
查看被添加新内容的父工程 pom.xml 下面 modules 和 module 标签是聚合功能的配置(自动生成)
<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> -->
-
在父工程中配置依赖的统一管理,夫工程中添加过的依赖,在子工程中不需要写版本号(若要指定,以子工程写的版本号为主)
-
在父工程中声明自定义属性
<!-- 通过自定义属性,统一指定Spring的版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 自定义标签,维护Spring版本数据 -->
<atguigu.spring.version>4.3.6.RELEASE</atguigu.spring.version>
</properties>
在需要的地方使用${}的形式来引用自定义的属性名:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${atguigu.spring.version}</version>
</dependency>
聚合
-
聚合本身的含义:部分组成整体
-
Maven 中的聚合
使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目。
-
项目:整体
-
模块:部分
-
-
概念的对应关系:
-
从继承关系角度来看:
-
父工程
-
子工程
-
-
从聚合关系角度来看:
-
总工程
-
模块工程
-
-
-
好处:一键执行 Maven 命令:很多构建命令都可以在“总工程”中一键执行。
-
聚合的配置
在总工程中配置 modules 即可
<modules>
<module>pro04-maven-module</module>
<module>pro05-maven-module</module>
<module>pro06-maven-module</module>
</modules>
5、依赖循环问题
如果 A 工程依赖 B 工程,B 工程依赖 C 工程,C 工程又反过来依赖 A 工程,那么在执行构建操作时会报 下面的错误:
DANGER [ERROR] [ERROR] The projects in the reactor contain a cyclic reference
这个错误的含义是:循环引用。
Maven工程在IDEA中的使用
创建工程
-
选择File–>New–>Project–>Maven
-
选择不勾选Create from archetype,直接点Next–>输入Groupid–>输入Artifactid–>Next–>将Name改成和Artifactid一致–>Finish
-
首次创建时,右下角方框选择Enable Auto-Import(自动导入)
-
配置Maven信息:Setting–>Build,Execution,Deployment–>Maven(直接点击Maven页面的扳手进入也行)–>
将Maven home directory改为自己下载的Maven文件–>User Setting File改为自己下载的Maven下的Setting.xml文件–>Local repository改为Maven本地厂库文件
-
创建Java模块工程:New Module–>Maven–>Next–>输入Name(Artifactid)–>Finish
-
创建Web模块工程:先创建Java工程–>在POM.xml中将 packageing>标签中的选项改为 war 打包方式
选择File–>Project Structure…–>左边选择Facets–>上面Web中点添加–>下面修改web.xml信息,选择笔(修改)–>在Artifactid工程名后添加src\main\webapp,下面的版本自行选择–>点击OK–>查看Web Resource directory中是否含有src\main\webapp–>OK–>YES–>Apply–>OK
在IDEA中执行Maven命令
-
直接运行
-
点击Maven目录的命令
-
手动输入
附录
在Maven中常用的命令
mvn archetype:generate | 命令生成Maven工程 |
---|---|
mvn clean | 删除 target 目录 |
mvn compile | 主程序编译 |
mvn test-compile | 测试程序编译 |
mvn test | 测试程序 |
mvn package | 打包程序 |
mvn install | 安装程序 |
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4 | 创建Web工程 |
mvn dependency:list | 查看当前 工程所依赖的 jar 包的列表 |
mvn dependency:tree | 以树形结构查看 |
在Maven中常用的标签
groupId> | 公司或组织的 id |
---|---|
artifactId> | 一个项目或者是项目中的一个模块的 id |
version | 版本号 |
dependencies> | 依赖库:内包含所有依赖depenency |
depenency> | 依赖:通过坐标来依赖其他jar包 |
scope> | 依赖的范围(常用):compile(默认值)/test/provided |
packaging> | 指定打包方式 |
excludes> | 排除库:配置依赖排除 |
exclusion> | 指定要排除的依赖的坐标(不需要写version) |
properties> | 在该标签中可自定义标签(使用 ${标签名} 引用) |
modules> | 聚合标签 |
---|---|
dependencyManagement --> dependencies --> dependency> | 继承时父工程中加入该标签 |