目录
1.简介
是一个Java项目管理和构建工具,可以定义项目结构、项目依赖,并使用统一的方式进行自动化构建
2.学习目的
-
提供了一套标准化的项目结构;
-
编码区
-
测试用例编码区
-
编译结果区
-
-
提供了一套标准化的构建流程(编译,测试,打包,发布...)
-
maven:
-
清理 clean
-
编译 compile
-
测试 test
-
报告
-
打包 package
-
部署 deploy
-
-
提供了一套以来管理机制(管理所有jar包)
-
引入仓库,存储管理jar包
-
jar之间的版本冲突,利用"以来传递",会将相关的jar包都引入进来,解决版本冲突
-
-
3.下载安装maven
-
maven是一个java工具,使用其必须安装java环境
-
maven官方地址:Maven – Welcome to Apache Maven
参考博客:maven的下载与安装教程(超详细)_maven安装-优快云博客
用mvn命令创建项目
下载
mvn archetype:generate
groupId:坐标 包名
artifactId:坐标 项目名
version:版本号
package:包名
脚手架:快速构建开发项目,完成项目基础的配置
4.项目结构
-
pom.xml :基础标志,标志是一个maven项目,是maven的配置文件
-
main文件夹:项目主体文件
-
java文件:.java
-
com.zmq:包,通过groupId生成的
-
resource文件:除了.java文件都可以放,一般放置 xml,properties,yaml等配置文件,静态资源文件,模板页
-
-
-
test文件夹:单元测试Junit @Test
-
java :.java
-
如果想在单元测试中,配置一些测试时i才会用到的配置文件则在test文件夹下添加resource文件夹
-
-
另外还有一个target目录专门存放构建输出的结果
5.约定目录结构的意义
maven是为了让构建过程尽可能的自动化完成。例如:Maven执行编译操作,必须先去Java源程序目录读取JAVA源代码,然后执行编译,最后将编译结果存放在target目录
6.约定大于配置
maven对于目录结构这个问题,没有采用配置的方式,基于约定。使得开发方便。
目前开发领域的技术发展趋势:约定大于配置,配置大于编码。
如何理解:
7.POM.xml
<?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">
<!--表示该pom.xml文件遵守的是Maven 4.0.0版本的项目模型规范。
这关乎到Maven是如何解析和处理POM文件中的配置信息的 -->
<modelVersion>4.0.0</modelVersion>
<!--设置打包方式,默认为jar-->
<packaging>jar</packaging>
<!--1.本工程基本坐标信息 确认jar包的位置
2.告诉Maven,会先根据这个坐标去本地仓库这个jar包,如果没有就去远程仓库下载(setting.xml中配置)
3.每个maven项目都有唯一的一个坐标,groupId+artifactId+version
-->
<!--配置工程坐标信息:
项目:
当前工程就是项目时
groupId:域名反过来 com.baidu
artifactId:项目名称 oa
version:版本号 1.0-SNAPSHOT 还没上线,最初的快照版
模块:OA有三个模块(前台,后台,common) - (聚合maven项目)
groupId:域名反过来加上项目 com.baidu.oa
artifactId:前台/后台/common
version:版本号 1.0-SNAPSHOT 还没上线,最初的快照版
-->
<groupId>com.dev.springBootDemo</groupId>
<artifactId>mavenDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--属性 通常设置依赖的版本
可以统一的管理版本-->
<properties>
<!--当前JDK版本 可以去掉-->
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--依赖把呢不能设置-->
<javax.servlet.version>3.1.0</javax.servlet.version>
</properties>
<!--依赖-->
<!--通过坐标信息去引用jar包,告诉Maven,先根据这个坐标去本地仓库这个jar包,如果没有就去远程仓库下载(setting.xml中配置)
去maven中央仓库中找 https://mvnrepository.com/
-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--依赖范围
编译(main/java):
测试(main/test):
运行/打包(包内):
test 编译x 测试ok 打包x junit
provided 编译ok 测试ok 打包x servlet tomcat中的jar可以设置
compile 编译ok 测试ok 打包ok 默认
runtime 编译x 测试ok 打包ok 数据库驱动,Class.forName()
system = provided 不会依赖仓库中的jar包,而是引用本地物理路径的jar包 <systemPath></systemPath>
1.首先,依赖范围只是建议,即使所有的范围都设置成compile,也不会影响功能正常使用
2.使用依赖提供的scope,直接从中央仓库进行复制,自动补全
3,90%的依赖都是compile
-->
<scope>test</scope>
</dependency>
</dependencies>
</project>
8.maven命令
命令执行位要在pom同级位置执行
mvn clean mvn compile
如果执行了package会先执行clean,validate,complie,test。按照生命周期执行
注意:test命令会执行test文件夹下的测试文件,且是以Test开头的
install
就是将当前项目按照生命周期依次执行clean...install,将package打包的jar/war传到本地仓库中
例如:
项目位置坐标信息:
<groupId>com.dev.springBootDemo</groupId>
<artifactId>mavenDemo</artifactId>
<version>1.0-SNAPSHOT</version>
maven仓库地址:
D:\developTools\configs\apache-maven-3.9.7\mvn_repository
install的jar包位置:
D:\developTools\configs\apache-maven-3.9.7\mvn_repository\com\dev\springBootDemo\mavenDemo\1.0-SNAPSHOT
为什么maven执行了install但是没有先执行clean?为什么不按照生命周期执行?
增量构建: 如果Maven检测到之前的构建结果仍然有效(即没有任何源码或依赖发生变化),它可能会跳过前置阶段(如
clean
),直接执行后续的阶段(如compile
、test
、install
等)。这种行为可以加快构建速度,特别是在大型项目中。命令行参数或配置: 可能在Maven命令行或配置文件中指定了跳过
clean
阶段的选项,例如使用-Dmaven.clean.skip=true
参数。构建插件或脚本: 在一些项目中,特定的构建脚本或自定义插件可能会覆盖Maven默认的构建行为,导致
clean
阶段被省略或调整了执行顺序。要确保按照Maven的标准生命周期执行阶段,可以考虑以下几点:
显式执行clean阶段: 在执行
install
之前,可以明确执行clean
阶段,确保每次构建都是从干净的状态开始。检查配置和插件: 确保项目的Maven配置和使用的插件没有自定义的设置导致
clean
阶段被跳过或修改执行顺序。考虑构建优化: 如果项目允许增量构建,可以配置Maven以便在需要时跳过
clean
阶段,从而提升构建效率。
9.maven生命周期
在Maven构建生命周期中,clean, validate, compile, test, package, verify, install, 和 deploy 是一系列预定义的构建阶段,每个阶段都有其特定的目的和使用场景。下面逐一解释这些阶段:
-
clean(清理):
-
作用: 清理之前构建产生的输出文件,比如删除target目录下的内容,以便于开始一个干净的构建过程。
-
使用场景: 当你需要重新构建项目,确保没有任何旧的构建结果干扰时使用。
-
-
validate(验证):
-
作用: 验证项目是否正确以及所有必要的信息是否可用,例如检查项目的基本结构是否完整。
-
使用场景: 在构建过程的早期阶段,确保项目的配置无误。
-
-
compile(编译):
-
作用: 编译项目的源代码,将Java源文件(位于src\main\java)编译为字节码(.class文件)。
-
使用场景: 构建过程的核心步骤,每次修改源代码后都需要执行。
-
-
test(测试):
-
作用: 运行项目的单元测试,这些测试代码通常位于src\test\java目录下。
-
使用场景: 开发过程中频繁执行,确保新添加或修改的代码没有引入错误。
-
-
package(打包):
-
作用: 根据项目类型打包编译后的代码,例如将Java项目打包成JAR或WAR文件。
-
使用场景: 构建完成后,准备分发或部署前的必要步骤。
-
-
verify(验证):
-
作用: 对打包的结果进行验证,确保符合质量标准,可能包括运行集成测试等。
-
使用场景: 确保打包后的产物满足预期的质量要求,通常在自动化构建流程中使用。
-
-
install(安装):
-
作用: 将打包好的构件安装到本地仓库,供本机其他Maven项目作为依赖使用。
-
使用场景: 成功构建并验证项目后,希望在本地开发环境中可用作依赖,将项目作为依赖引入到其他项目中的关键步骤。
-
-
deploy(部署):
-
作用: 将最终的包部署到远程仓库,供其他开发者或持续集成/持续部署(CI/CD)流程使用。
-
使用场景: 发布版本时,将完成的构建产物上传至公司内部或公共的Maven仓库。
-
每个阶段依赖于前一个阶段的输出,构成了一个有序的构建流程。例如,compile
依赖于validate
和clean
,test
依赖于compile
,依此类推。Maven按照这些定义好的生命周期阶段顺序执行,确保了项目的一致性和可靠性。
10.依赖的范围
关于依赖范围的解释:
-
test: 该范围的依赖只在编译测试代码和运行测试时使用,不会包含在最终的打包产物中。适用于如JUnit这样的测试库。
-
provided: 表示该依赖在编译和测试时需要,但在运行时不需要,因为容器或JDK已经提供了。如Servlet API在Tomcat中就是如此。
-
compile(默认): 编译、测试和打包时都会用到的依赖,是最常见的依赖范围。
-
runtime: 不参与编译过程,但会在运行时和打包时加入,适用于JDBC驱动这类运行时才需要的库。
-
system: 类似于provided,但是不从Maven仓库获取,而是通过指定本地文件系统上的路径来使用。较少使用,通常避免此做法。
<!--依赖范围
编译(main/java):
测试(main/test):
运行/打包(包内):
test 编译x 测试ok 打包x junit
provided 编译ok 测试ok 打包x servlet tomcat中的jar可以设置
compile 编译ok 测试ok 打包ok 默认
runtime 编译x 测试ok 打包ok 数据库驱动,Class.forName()
system = provided 不会依赖仓库中的jar包,而是引用本地物理路径的jar包 <systemPath></systemPath>
1.首先,依赖范围只是建议,即使所有的范围都设置成compile,也不会影响功能正常使用
2.使用依赖提供的scope,直接从中央仓库进行复制,自动补全
3,90%的依赖都是compile
-->
<scope>test</scope>
反射:
Class<?> aClass = Class.forName("javax.servlet.Servlet"); Object o = aClass.newInstance();// new Servlet();
11.依赖传递
如果A项目要想引用B项目,首先B项目要先install到本地仓库中才行,且是jar包(war包不行)
如果A不想引用B中的依赖
1.在B中相应依赖可设置范围,<scope></scope>(test或者provided就不会传递)
2.设置<optional></optional> (默认是false,会传递,改成true就不会传递)
3.A中排除掉即可<exclusions><exclusion></exclusion></exclusions>
4.如果A中也有B中的依赖,版本不一样则A会将B覆盖,当前工程依赖优先(与位置前后无关)
12.依赖排除和覆盖
13.maven中show Diagram详解
作用于类
num 按钮 功能 1 Fields 域 2 Constructors 构造器 3 Method 方法 4 Properties 属性 5 Inner Class 内部类 6 Change Visibility Level 更改可见性级别 7 Change Scope 改变范围 8 Edge Creation Mode 边缘创建模式 9 Show Dependencies 显示依赖关系 Apply Current Layout(F5) 应用当前布局
-
type右键->Diagrams->Show Diagrams, 可以看到本类以及本类的父类/接口。
那么如何查看本类的Implementation?
-
首先在上面得到的类图中删掉所有其它类,再右键本类->Show Implementations
作用于pom
-
点这里查看Maven的依赖关系图:
-
结果:
14.maven聚合
1.聚合本身含义
一个项目拆成多个工程
不写代码 只进行管理工程
2.maven中的聚合
15.maven继承
解决:
当一个依赖是子项目不一定要的时候: