- Maven
- maven的作用
- Maven下载和配置
- 创建Maven项目
- Maven项目结构
- 约定目录结构的意义
- 约定大于配置
- Maven命令
- 依赖范围
- 依赖传递
- 依赖的排除和覆盖
- 依赖图
- Maven聚合和继承
- 聚合
- 继承
- Maven命令复制依赖
- pom.xml文件解析
- 父工程
- 子工程1
- 子工程2
- 下载依赖流程
- 参考
Maven
Maven是一个Java项目管理和构建的工具,它可以定义项目结构、项目依赖管理、使用统一的方式进行自动化构建,是Java项目不可或缺的工具。
maven的作用
- 提供了一套标准化的项目结构。
- 以前不用的开发工具项目结构不一样,maven出现后规范了项目结构,开发人员上手项目变得更加简单。
-
提供了一套标准化的构建流程(编译,测试,打包,发布...)。
-
提供了一套依赖管理机制(pom.xml文件,管理项目中的所有jar包)。
- 使用传统的项目开发,每次都要复制jar包到lib目录,如果jar包很多,项目大小会很大,且多个项目的话,使用同一个包需要复制多份。
- maven管理后,所有jar包都存在maven仓库,只需要用pom.xml管理jar包。
- 解决jar包和jar包的版本冲突问题(利用"依赖传递"特性解决)。
Maven下载和配置
Maven下载和配置 简要步骤及注意事项:
-
maven是一个java工具,它必须有java环境,配置java环境保留。
-
下载版本可参考idea默认绑定的maven版本。
-
修改配置:主要修改镜像和仓库位置。
-
Maven 中央仓库:默认运程仓库是 Maven 中央仓库(repo.maven.apache.org),它是官方的、最全的公共仓库,但服务器在国外,国内访问速度可能较慢。
-
镜像:Maven 中央仓库(Central Repository)在国内的一个“完整拷贝”(或称“镜像”),定期同步,以保证内容一致。
-
镜像的作用:拦截原本对Maven 中央仓库的请求,并将其重定向到镜像地址。对用户来说,这个过程是透明的,感觉不到区别,由于镜像在国内,下载速度会快很多。
-
-
IDEA配置Maven。
创建Maven项目
maven命令创建
-
mvn archetype:generate
idea创建
Maven项目结构
另外还有一个target目录专门存放构建操作输出的结果。
约定目录结构的意义
Maven为了让构建过程能够尽可能自动化完成,所以必须约定目录结构的作用。例如: Maven执行编译操作,必须先去Java源程序目录读取Java源代码,然后执行编译,最后把编译结果存放在target目录。
约定大于配置
Maven对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常方便。如果每次创建Maven工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:约定大于配置,配置大于编码。
Maven命令
命令行:注意要在pom.xml所在的目录下执行命令
idea自带的界面执行:
生命周期:例如执行compile时,其实会依次执行 clean、valiate、compile
Maven 生命周期命令作用:
clean - 清理项目,删除target目录
validate - 验证项目正确性和所需信息是否可用
compile - 编译项目源代码
test - 运行单元测试
package - 打包编译后的代码(jar、war等格式)
verify - 检查集成测试结果以确保质量标准
install - 将包安装到本地仓库,供其他项目使用
site - 生成项目站点文档
deploy - 将最终包复制到远程仓库
这些命令按顺序执行,构成Maven的标准构建生命周期。
依赖范围
依赖范围:compile(默认)、provided、runtime、system、test
有哪些范围:测试(main.java)、编译(test.java)、运行/打包(包内)
-
test: 编译× 测试✔ 打包×
- 例如:junit 测试的时候才能用(main.java文件夹下的能用),编译、打包不能用。
-
provided:编译✔ 测试✔ 打包×
- 例如:javax.servlet(一般用tomcat启动,tomcat里已经有了javax.servlet,项目打包不用带这个包了,带了反而可能导致servlet版本混乱、项目增大)。
-
compile:编译✔ 测试✔ 打包✔
- 默认的。
-
runtime:编译× 测试✔ 打包✔
- 反射 数据库驱动class.forName()。
-
system:效果等于provided,但是其不会依赖仓库中jar包,而是引用本地物理路径的jar包 。
-
基本不会使用,了解即可。
-
使用时配合一个
使用。
-
1.首先﹑依赖范围建议﹑哪怕所有的范围都设置compile,也不会影响功能正常使用。
2.使用依赖提供的scope,直接中央仓库无脑复制就行了,并且idea也会自动补全。
3.90%以上都会使用compile。
4.但是如果做一个好的程序员,应该尽量让程序优雅,保证依赖的最小范围。
依赖传递
<dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.40</version><! --作用访问是test、provided 就不会传递<scope>provided</scope> --><!--是否传递 默认是于false 会传递--><optional>false</optional></dependency>
</dependencies>
依赖的排除和覆盖
<!-- com.test.project 里面有一个依赖我们不需要的情况,或者版本不需要的情况,用下面的方式解决--><dependency><groupId>com.test</groupId><artifactId>bproject</artifactId><version>1.0-SNAPSHOT</version><!-- 手动排除<exclusions><exclusion><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></exclusion></exclusions>-->
</dependency><!--在自己的工程添加一个系统的依赖,不同版本会以我们工程依赖优先进行替换-->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.2.0</version>
</dependency>
依赖图
商业版的idea才有
Maven聚合和继承
聚合:主要关注的是项目的物理结构和构建过程。
- 将多个独立的 Maven 项目(模块)组合在一起,以便通过一个统一的入口(父 POM)来一次性构建所有这些项目。
- 子项目直接可以互相直接引用,而不需要install
继承:主要关注的是POM 配置的逻辑关系和复用性。
- 允许子模块 POM 从一个共同的父 POM 中继承配置信息,从而实现配置的复用和统一管理。
聚合
聚合项目:
-
把src删掉,因为聚合项目通常只是管理子工程。
-
把packaging修改下默认jar,改成pom,当前不是一个具体的包。
-
把子工程管理起来。
<packaging>pom</packaging>
<modules><module>maven_01</module><module>maven_02</module>
</modules>
继承
<parent><groupId>org.example</groupId><artifactId>MavenTest</artifactId><version>1.0-SNAPSHOT</version>
</parent>
Maven命令复制依赖
dependency:copy-dependencies
:用于将项目依赖的jar包从仓库拷贝到指定目录。
-
如果子工程都没引入其他的依赖:
-
例如父工程引入
5.8.40 ,子过程都没引入其他版本。 -
那么复制过来的就都是父工程配置的依赖:
5.8.40 。
-
-
如果一个子工程引入其他的依赖,其他用父工程的:
- 例如父工程引入
5.8.40 ,子工程1未引入,直接用父工程的,子工程25.8.39 。 - 那么复制过来的就都是父工程配置的和子工程2配置的依赖:
5.8.40 、5.8.39 。
- 例如父工程引入
-
如果所有子工程引入新的版本,但是都是同一个:
-
例如父工程
5.8.40 ,所有子工程包括子过程1和子工程2都引入5.8.38 。 -
那么复制过来的就都是子过程1和子工程2配置的依赖:
5.8.38 。 -
如果所有子工程引入新的版本,但是不是同一个:
- 例如父工程
5.8.40 ,子工程15.8.38 ,子工程25.8.39 。 - 那么复制过来的就是子过程1和子工程2配置的依赖:
5.8.38 、5.8.39 。
- 例如父工程
总结就是:【父工程】的依赖会传递给【子工程】用,但是【子工程】重新导入的依赖会覆盖【父工程】传递过来的。
mvn clean install dependency:copy-dependencies -DoutputDirectory=D:\file\IDEA_File\mylib -DincludeScope=compile -Dsilent=true -Dmdep.cpPom=false -DskipTests -T 4mvn clean install dependency:copy-dependencies -DoutputDirectory=D:\file\IDEA_File\mylib -DincludeScope=compile -Dsilent=true "-Dmdep.cpPom=false" -DskipTests -T 4// 会把父工程和子过程里面所有导入的依赖里的jar包复制到D:\ToolOfProductionData\IDEAFile\MavenTest\mylib中
// 如果子工程都没引入其他的依赖:那么复制过来的就都是父工程配置的依赖
// 如果子工程引入的版本都是同一个:例如父工程
mvn clean install dependency:copy-dependencies -DoutputDirectory=D:\ToolOfProductionData\IDEAFile\MavenTest\mylib -DincludeScope=compile -Dsilent=true "-Dmdep.cpPom=false" -DskipTests -T 4
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"><!-- 无视 maven版本相关 --><modelVersion>4.0.0</modelVersion><!-- 坐标信息 本工程的坐标信息 每个项目都有一个唯一的坐标信息 --><!--怎么配置本工程的坐标信息:项目:groupId: 域名反过来 com.baiduartifactId: 项目名字version: 版本 1.0-SNAPSHOT SNAPSHOT:还没上线的最初的快照版本模块:前台、后台、公共模块groupId: 域名反过来+项目名字 com.baidu.项目名字artifactId: 模块名字version: 版本 1.0-SNAPSHOT SNAPSHOT:还没上线的最初的快照版本--><groupId>org.example</groupId><artifactId>MavenTest</artifactId><version>1.0-SNAPSHOT</version><!-- 设置打包方式 默认是jar 常用的:jar war pom --><packaging>pom</packaging><modules><module>maven_01</module><module>maven_02</module></modules><!-- 属性 变量通常设置依赖的版本:统一管理版本--><properties><!-- 当前jdk版本 其实一般不会在这里设置,idea启动项目里面已经设置了,其实这里可以删除 --><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包,准确说是引入依赖,因为一个依赖会有多个jar包 --><!-- 找依赖的地址: https://mvnrepository.com/ --><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.4</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>${javax.servlet.version}</version><!--依赖范围:compile(默认)、provided、runtime、system、test有哪些范围:测试(main.java)、编译(test.java)、运行/打包(包内)test: 编译× 测试✔ 打包× 例如:junit 测试的时候才能用(main.java文件夹下的能用),编译、打包不能用provided:编译✔ 测试✔ 打包× 例如:javax.servlet(一般用tomcat启动,tomcat里已经有了javax.servlet,项目打包不用带这个包了,带了反而可能导致servlet版本混乱、项目增大)compile:编译✔ 测试✔ 打包✔ 默认的runtime:编译× 测试✔ 打包✔ 反射 数据库驱动class.forName()system:基本不会使用,了解即可 效果等于provided,但是其不会依赖仓库中jar包,而是引用本地物理路径的jar包 使用时配合一个<systemPath></systemPath>使用1.首先﹑依赖范围建议﹑哪怕所有的范围都设置compile,也不会影响功能正常使用。2.使用依赖提供的scope,直接中央仓库无脑复制就行了,并且idea也会自动补全。3.90%以上都会使用compile。4.但是如果做一个好的程序员,应该尽量让程序优雅,保证依赖的最小范围。--><scope>compile</scope></dependency></dependencies><!-- 对于子工程必须要的依赖,可以放在dependencies这里,直接传递给子项目--><!-- 对于子工程不是必须要的依赖,可以放在dependencyManagement这里,子工程引入时不需要版本,因为这里控制了--><dependencyManagement><dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.40</version></dependency></dependencies></dependencyManagement>
</project>
子工程1
<?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><parent><groupId>org.example</groupId><artifactId>MavenTest</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>maven_01</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.43</version></dependency></dependencies></project>
子工程2
<?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><parent><groupId>org.example</groupId><artifactId>MavenTest</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>maven_02</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency></dependencies>
</project>
下载依赖流程
参考
参考视频:7、依赖引用_哔哩哔哩_bilibili