当前位置: 首页 > news >正文

maven

目录
  • Maven
    • maven的作用
    • Maven下载和配置
    • 创建Maven项目
    • Maven项目结构
      • 约定目录结构的意义
      • 约定大于配置
    • Maven命令
    • 依赖范围
    • 依赖传递
    • 依赖的排除和覆盖
    • 依赖图
    • Maven聚合和继承
      • 聚合
      • 继承
    • Maven命令复制依赖
    • pom.xml文件解析
      • 父工程
      • 子工程1
      • 子工程2
    • 下载依赖流程
    • 参考

Maven

Maven是一个Java项目管理和构建的工具,它可以定义项目结构、项目依赖管理、使用统一的方式进行自动化构建,是Java项目不可或缺的工具。

maven的作用

  1. 提供了一套标准化的项目结构。
    • 以前不用的开发工具项目结构不一样,maven出现后规范了项目结构,开发人员上手项目变得更加简单。

image-20250921132319078

  1. 提供了一套标准化的构建流程(编译,测试,打包,发布...)。

    image-20250921132547791

  2. 提供了一套依赖管理机制(pom.xml文件,管理项目中的所有jar包)

    • 使用传统的项目开发,每次都要复制jar包到lib目录,如果jar包很多,项目大小会很大,且多个项目的话,使用同一个包需要复制多份。
    • maven管理后,所有jar包都存在maven仓库,只需要用pom.xml管理jar包。
    • 解决jar包和jar包的版本冲突问题(利用"依赖传递"特性解决)。

Maven下载和配置

Maven下载和配置 简要步骤及注意事项:

  1. maven是一个java工具,它必须有java环境,配置java环境保留。

  2. 下载版本可参考idea默认绑定的maven版本。

  3. 修改配置:主要修改镜像和仓库位置。

    • Maven 中央仓库:默认运程仓库是 Maven 中央仓库(repo.maven.apache.org),它是官方的、最全的公共仓库,但服务器在国外,国内访问速度可能较慢。

    • 镜像:Maven 中央仓库(Central Repository)在国内的一个“完整拷贝”(或称“镜像”),定期同步,以保证内容一致。

    • 镜像的作用:拦截原本对Maven 中央仓库的请求,并将其重定向到镜像地址。对用户来说,这个过程是透明的,感觉不到区别,由于镜像在国内,下载速度会快很多。

  4. IDEA配置Maven。

创建Maven项目

maven命令创建

  • mvn archetype:generate
    

idea创建

image-20250921140112563

Maven项目结构

image-20250921140601557

另外还有一个target目录专门存放构建操作输出的结果。

约定目录结构的意义

Maven为了让构建过程能够尽可能自动化完成,所以必须约定目录结构的作用。例如: Maven执行编译操作,必须先去Java源程序目录读取Java源代码,然后执行编译,最后把编译结果存放在target目录。

约定大于配置

Maven对于目录结构这个问题,没有采用配置的方式,而是基于约定。这样会让我们在开发过程中非常方便。如果每次创建Maven工程后,还需要针对各个目录的位置进行详细的配置,那肯定非常麻烦。
目前开发领域的技术发展趋势就是:约定大于配置,配置大于编码。

Maven命令

命令行:注意要在pom.xml所在的目录下执行命令

image-20250921144704473

idea自带的界面执行:

image-20250921132547791

生命周期:例如执行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.但是如果做一个好的程序员,应该尽量让程序优雅,保证依赖的最小范围。

依赖传递

image-20250921152154156

<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才有

image-20250921152926852

image-20250921153004550

Maven聚合和继承

聚合:主要关注的是项目的物理结构和构建过程。

  • 将多个独立的 Maven 项目(模块)组合在一起,以便通过一个统一的入口(父 POM)来一次性构建所有这些项目。
  • 子项目直接可以互相直接引用,而不需要install

继承:主要关注的是POM 配置的逻辑关系和复用性。

  • 允许子模块 POM 从一个共同的父 POM 中继承配置信息,从而实现配置的复用和统一管理。

聚合

聚合项目:

  1. 把src删掉,因为聚合项目通常只是管理子工程。

  2. 把packaging修改下默认jar,改成pom,当前不是一个具体的包。

  3. 把子工程管理起来。

<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.405.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.385.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>

下载依赖流程

image-20250921143017835

参考

参考视频:7、依赖引用_哔哩哔哩_bilibili

http://www.hskmm.com/?act=detail&tid=12078

相关文章:

  • 第十一届中国大学生程序设计竞赛网络预选赛(CCPC Online 2025)
  • 网络流
  • 完整教程:数据结构 栈和队列、树
  • 深入解析:【ubuntu】ubuntu中找不到串口设备问题排查
  • 酵母双杂交技术:高通量筛选的突破与不可忽视的三大局限性
  • ubuntu20.04测试cuda
  • Android Studio 配置国内源
  • PyCharm项目上传GitHub仓库(笔记) - 教程
  • 从RAG出发
  • 软件工程第二次作业——第一次个人编程作业
  • Ubuntu 24.04 安装 DaVinci Resolve
  • Promise中处理请求超时问题
  • 图解26:老生常谈的OSI网络模型
  • 【C++】指针
  • AI驱动建筑行业数字化转型
  • 详细介绍:前端学习——CSS
  • VSCode 把代码发送到激活状态下的终端
  • 线性结构之数组[基于郝斌课程]
  • 完整教程:Vue中的props方式
  • 图解25:MySQL主从复制原理
  • 用 Go 编写验证码识别脚本(基于 Tesseract)
  • 软工第二次作业
  • Zero-Shot、One-Shot、Few-Shot概念
  • ADS放入元器件include和DK.zip文件依然提示未定义
  • AI元人文(十三):良知觉醒——论三值伦理模型与元道德主体的诞生
  • 「MCOI-05」魔仙
  • BlueHat v18 会议资料现已发布:前沿安全技术与漏洞缓解策略
  • label和brand的区别(品牌=brand?错了,你们的英语都学错了!)
  • 2025.9.21——1绿
  • 故障处理:ORA-04031真实案例分享