Jtoss Jtoss
首页
  • 数据结构与算法

    • 数据结构与算法 - 概述
    • 数据结构与算法 - 复杂度分析
    • 数据结构 - 线性表
    • 算法 - 常见排序算法
  • 代码规范

    • 代码简洁之道
    • 阿里巴巴开发手册
    • 谷歌Java编程风格指南
  • 设计模式

    • 编写高质量代码概述
    • 面向对象
    • 设计原则
    • 设计模式-创建型
    • 设计模式-结构型
    • 设计模式-行为型(上)
    • 设计模式-行为型(下)
    • 浅析框架源码中的设计模式
    • 业务框架实战案例
  • MySQL 基础

    • MySQL - 数据库设计规范
    • MySQL - 必知必会
  • MySQL 进阶

    • MySQL - 基础架构
    • MySQL - InnoDB存储引擎
    • MySQL - InnoDB缓冲池
    • MySQL - 事务与锁
    • MySQL - 索引
    • MySQL - 查询执行计划
    • MySQL - 性能优化
  • Redis 系列

    • Redis入门 - 基础相关
    • Redis进阶 - 数据结构
    • Redis进阶 - 持久化RDB和AOF
    • Redis进阶 - 事件机制
    • Redis进阶 - 事务
    • Redis进阶 - 高可用高可扩展
    • Redis进阶 - 缓存问题
    • Redis进阶 - 性能调优
  • Java 基础

    • Java 基础 - 知识点
    • Java 基础 - 面向对象
    • Java 基础 - Q/A
  • Java 进阶 - 集合框架

    • Java 集合框架详解
  • Java 进阶 - 多线程与并发

    • Java 并发 - 理论基础
    • Java 并发 - 线程基础
    • Java 并发 - 各种锁
    • Java 并发 - 关键字 volatile
    • Java 并发 - 关键字 synchronized
    • JUC - CAS与原子操作
    • JUC - 锁核心类AQS
    • JUC - 锁接口和类简介
    • JUC - 并发容器简介
    • JUC - 通信工具类
    • JUC - Fork-Join框架
    • JUC - 线程池
  • Java 进阶 - JVM

    • JVM - 概述
    • JVM - 类加载机制
    • JVM - 内存结构
    • JVM - 垃圾回收机制
    • JVM - 性能调优
  • Maven系列

    • Maven基础知识
    • Maven项目构建
    • Maven多模块配置
  • Spring 框架

    • Spring 框架 - 框架介绍
    • Spring 框架 - IOC详解
    • Spring 框架 - AOP详解
    • Spring 框架 - SpringMVC详解
  • Spring Boot 系列

    • Spring Boot - 开发入门
    • Spring Boot - 接口相关
  • Spring Cloud 系列
  • Mybatis 系列

    • Mybatis - 总体框架设计
    • Mybatis - 初始化基本过程
    • Mybatis - sqlSession执行过程
    • Mybatis - 插件机制
    • Mybatis - 事务管理机制
    • Mybatis - 缓存机制
  • 业务常见问题

    • Java 业务开发常见错误(一)
    • Java 业务开发常见错误(二)
    • Java 业务开发常见错误(三)
    • Java 业务开发常见错误(四)
    • Java 业务开发常见错误(五)
    • Java 业务开发常见错误(六)
  • IDEA系列

    • IDEA 2021开发环境配置
    • IDEA 快捷键
  • Git系列

    • git status中文乱码
  • 其他

    • Typora+Picgo 自动上传图片
    • hsdis 和 jitwatch
  • 实用技巧
  • 收藏
  • 摄影
  • 学习
  • 标签
  • 归档

Jason Huang

后端程序猿
首页
  • 数据结构与算法

    • 数据结构与算法 - 概述
    • 数据结构与算法 - 复杂度分析
    • 数据结构 - 线性表
    • 算法 - 常见排序算法
  • 代码规范

    • 代码简洁之道
    • 阿里巴巴开发手册
    • 谷歌Java编程风格指南
  • 设计模式

    • 编写高质量代码概述
    • 面向对象
    • 设计原则
    • 设计模式-创建型
    • 设计模式-结构型
    • 设计模式-行为型(上)
    • 设计模式-行为型(下)
    • 浅析框架源码中的设计模式
    • 业务框架实战案例
  • MySQL 基础

    • MySQL - 数据库设计规范
    • MySQL - 必知必会
  • MySQL 进阶

    • MySQL - 基础架构
    • MySQL - InnoDB存储引擎
    • MySQL - InnoDB缓冲池
    • MySQL - 事务与锁
    • MySQL - 索引
    • MySQL - 查询执行计划
    • MySQL - 性能优化
  • Redis 系列

    • Redis入门 - 基础相关
    • Redis进阶 - 数据结构
    • Redis进阶 - 持久化RDB和AOF
    • Redis进阶 - 事件机制
    • Redis进阶 - 事务
    • Redis进阶 - 高可用高可扩展
    • Redis进阶 - 缓存问题
    • Redis进阶 - 性能调优
  • Java 基础

    • Java 基础 - 知识点
    • Java 基础 - 面向对象
    • Java 基础 - Q/A
  • Java 进阶 - 集合框架

    • Java 集合框架详解
  • Java 进阶 - 多线程与并发

    • Java 并发 - 理论基础
    • Java 并发 - 线程基础
    • Java 并发 - 各种锁
    • Java 并发 - 关键字 volatile
    • Java 并发 - 关键字 synchronized
    • JUC - CAS与原子操作
    • JUC - 锁核心类AQS
    • JUC - 锁接口和类简介
    • JUC - 并发容器简介
    • JUC - 通信工具类
    • JUC - Fork-Join框架
    • JUC - 线程池
  • Java 进阶 - JVM

    • JVM - 概述
    • JVM - 类加载机制
    • JVM - 内存结构
    • JVM - 垃圾回收机制
    • JVM - 性能调优
  • Maven系列

    • Maven基础知识
    • Maven项目构建
    • Maven多模块配置
  • Spring 框架

    • Spring 框架 - 框架介绍
    • Spring 框架 - IOC详解
    • Spring 框架 - AOP详解
    • Spring 框架 - SpringMVC详解
  • Spring Boot 系列

    • Spring Boot - 开发入门
    • Spring Boot - 接口相关
  • Spring Cloud 系列
  • Mybatis 系列

    • Mybatis - 总体框架设计
    • Mybatis - 初始化基本过程
    • Mybatis - sqlSession执行过程
    • Mybatis - 插件机制
    • Mybatis - 事务管理机制
    • Mybatis - 缓存机制
  • 业务常见问题

    • Java 业务开发常见错误(一)
    • Java 业务开发常见错误(二)
    • Java 业务开发常见错误(三)
    • Java 业务开发常见错误(四)
    • Java 业务开发常见错误(五)
    • Java 业务开发常见错误(六)
  • IDEA系列

    • IDEA 2021开发环境配置
    • IDEA 快捷键
  • Git系列

    • git status中文乱码
  • 其他

    • Typora+Picgo 自动上传图片
    • hsdis 和 jitwatch
  • 实用技巧
  • 收藏
  • 摄影
  • 学习
  • 标签
  • 归档
  • Maven系列

    • Maven基础知识
    • Maven项目构建
      • 目录结构
      • Maven 项目生命周期与构建原理
        • Maven 三大项目生命周期
        • Maven 对项目默认生命周期的抽象
        • Maven 各生命阶段行为绑定
      • 依赖原则
        • 依赖路径最短优先原则
        • 声明顺序优先原则
        • 覆写优先原则
        • 解决依赖冲突
      • 项目中依赖的搜索顺序
        • 依赖仓库的配置方式
        • 分析依赖搜索顺序
        • 准备测试环境
        • 默认情况
        • 配置镜像仓库 settings_mirror
        • 配置 pom 中的仓库 pom_repositories
        • 配置全局 profile 仓库 settingsprofilerepo
        • 配置项目 profile 仓库 pomprofilerepo
        • 最后确认 local_repo 本地仓库~/.m2/repository
        • 最终结论
      • 参考
    • Maven多模块配置
  • Spring 框架

  • Spring Boot

  • Spring Cloud

  • Spring
  • Maven系列
Jason
目录

Maven项目构建

# Maven 项目构建

# 目录结构

让我们来看一下功能的划分:

mvm-project-overview

# Maven 项目生命周期与构建原理

# Maven 三大项目生命周期

  • 默认构建生命周期 (Default Lifeclyle): 该生命周期表示这项目的构建过程,定义了一个项目的构建要经过的不同的阶段。
  • 清理生命周期 (Clean Lifecycle): 该生命周期负责清理项目中的多余信息,保持项目资源和代码的整洁性。一般拿来清空 target 目录下的文件。
  • 站点管理生命周期 (Site Lifecycle) : 向我们创建一个项目时,我们有时候需要提供一个站点,来介绍这个项目的信息,如项目介绍,项目进度状态、项目组成成员,版本控制信息,项目javadoc索引信息等等。站点管理生命周期定义了站点管理过程的各个阶段。

maven-3-lifecycle

# Maven 对项目默认生命周期的抽象

Maven根据一个项目的生命周期的每个阶段,将一个项目的生命周期抽象成了如上图所示的 23 个阶段。而每一个阶段应该干什么事情由用户决定。换句话说 maven 为每一个阶段设计了接口,你可以为每一阶段自己定义一个接口,进而实现对应阶段应该有的行为。

maven-lifecycle-phases

在经历这些生命周期的阶段中,每个阶段会理论上会有相应的处理操作。但是,在实际的项目开发过程中, 并不是所有的生命周期阶段都是必须的。 基于类似的约定,maven 默认地为一些不同类型的 maven 项目生命周期的阶段实现了默认的行为。

Maven 在设计上将生命周期阶段的抽象和对应阶段应该执行的行为实现分离开,maven 这些实现放到了插件中,这些插件本质上是实现了maven留在各个生命周期阶段的接口。 如下图所示,maven 针对不同打包类型的 maven 项目的生命周期阶段绑定了对应的默认行为:

maven-plugins-bind

# Maven 各生命阶段行为绑定

maven会根据 Mojo 功能的划分,将具有相似功能的 Mojo 放到一个插件中。并且某一个特定的 Mojo 能实现的功能称为 goal,即目标,表明该Mojo能实现什么目标。

maven-lifecycle-binds

例如,我们项目生命周期有两个阶段: compile 和 test-compile,这两阶段都是需要将Java源代码编译成class文件中,相对应地,compile和test-compiler分别被绑定到了org.apache.maven.plugin.compiler.CompilerMojo 和org.apache.maven.plugin.compiler.TestCompilerMojo上:

maven-compile-test-compile-binds

# 依赖原则

# 依赖路径最短优先原则

A -> B -> C -> X(1.0)
A -> D -> X(2.0)
1
2

由于 X(2.0) 路径最短,所以使用 X(2.0)。

# 声明顺序优先原则

A -> B -> X(1.0)
A -> C -> X(2.0)
1
2

在 POM 中最先声明的优先,上面的两个依赖如果先声明 B,那么最后使用 X(1.0)。

# 覆写优先原则

子 POM 内声明的依赖优先于父 POM 中声明的依赖。

# 解决依赖冲突

找到 Maven 加载的 Jar 包版本,使用 mvn dependency:tree 查看依赖树,根据依赖原则来调整依赖在 POM 文件的声明顺序。

# 项目中依赖的搜索顺序

# 依赖仓库的配置方式

maven 项目使用的仓库一共有如下几种方式:

  1. 中央仓库,这是默认的仓库
  2. 镜像仓库,通过 sttings.xml 中的 settings.mirrors.mirror 配置
  3. 全局 profile 仓库,通过 settings.xml 中的 settings.repositories.repository 配置
  4. 项目仓库,通过 pom.xml 中的 project.repositories.repository 配置
  5. 项目 profile 仓库,通过 pom.xml 中的 project.profiles.profile.repositories.repository 配置
  6. 本地仓库

如果所有配置都存在,依赖的搜索顺序就会变得异常复杂。

# 分析依赖搜索顺序

先从最简单开始,慢慢增加配置,查看有什么变化。

# 准备测试环境

安装 jdk、maven。并使用如下命令创建测试项目:

mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp  -DinteractiveMode=true -DgroupId=com.pollyduan -DartifactId=myweb -Dversion=1.0 -Dpackage=com.pollyduan
1

创建完成后,为了避免后续测试干扰,先执行一次 compile。

cd myweb
mvn compile
1
2

最后,修改 pom.xml 文件,将 junit 版本号改为 4.12 。我们要使用这个 jar 来测试依赖的搜索顺序。

# 默认情况

首先确保 junit4.12 不存在:

rm -rf ~/.m2/repository/junit/junit/4.12
1

默认情况下没有配置任何仓库,也就是说,既没改 $M2_HOME/conf/settings.xml 也没有添加~/.m2/settings.xml

执行编译,查看日志中拉取 junit 的仓库。

mvn compile

...
Downloaded from central: https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.pom (24 kB at 11 kB/s)
1
2
3
4

可以看出,默认是从 central 中央仓库拉取的 jar.

# 配置镜像仓库 settings_mirror

创建~/.m2/setttings.xml ,内容如下:

<settings>
  <mirrors>
    <mirror>
      <id>settings_mirror</id>
      <url>https://maven.aliyun.com/repository/public</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
</settings>
1
2
3
4
5
6
7
8
9

重新测试:

rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile
1
2

在日志中查看下载依赖的仓库:

Downloaded from settings_mirror: https://maven.aliyun.com/repository/public/junit/junit/4.12/junit-4.12.pom (24 kB at 35 kB/s)
1
  • 可以看出,是从 settings_mirror 中下载的 jar
  • 结论:settings_mirror 的优先级高于 central

# 配置 pom 中的仓库 pom_repositories

在 project 中增加如下配置:

<repositories>
  <repository>
    <id>pom_repositories</id>
    <name>local</name>
    <url>http://10.18.29.128/nexus/content/groups/public/</url>
    <releases>
      <enabled>true</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 由于我们改变了 id 的名字,所以仓库地址无所谓,使用相同的地址也不影响测试。

执行测试:

rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile
1
2

在日志中查看下载依赖的仓库:

Downloaded from pom_repositories: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 95 kB/s)
1

从显示的仓库 id 可以看出:

  • jar 是从 pom_repositories 中下载的。
  • pom_repositories 优先级高于 settings_mirror

# 配置全局 profile 仓库 settings_profile_repo

在~/.m2/settings.xml 中 settings 的节点内增加:

<profiles>
  <profile>
  <id>s_profile</id>
  <repositories>
    <repository>
      <id>settings_profile_repo</id>
      <name>netease</name>
      <url>http://mirrors.163.com/maven/repository/maven-public/</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>
  </profile>
</profiles>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

执行测试:

rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Ps_profile
1
2

在日志中查看下载依赖的仓库:

Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 63 kB/s)
1

从显示的仓库 id 可以看出:

  • jar 是从 settings_profile_repo 中下载的。
  • settings_profile_repo 优先级高于 settings_mirror。
  • settings_profile_repo 优先级高于 pom_repositories 。

# 配置项目 profile 仓库 pom_profile_repo

<profiles>
  <profile>
    <id>p_profile</id>
    <repositories>
      <repository>
        <id>pom_profile_repo</id>
        <name>local</name>
        <url>http://10.18.29.128/nexus/content/groups/public/</url>
        <releases>
          <enabled>true</enabled>
        </releases>
        <snapshots>
          <enabled>true</enabled>
        </snapshots>
      </repository>
    </repositories>
  </profile>
</profiles>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

执行测试:

rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Ps_profile,p_profile
mvn compile -Pp_profile,s_profile
1
2
3

在日志中查看下载依赖的仓库:

Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 68 kB/s)
1

从显示的仓库 id 可以看出:

  • jar 是从 settings_profile_repo 中下载的
  • settings_profile_repo 优先级高于 pom_profile_repo

进一步测试:

rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Pp_profile
1
2

在日志中查看下载依赖的仓库:

Downloaded from pom_profile_repo: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 106 kB/s)
1

从显示的仓库 id 可以看出:

  • jar 是从 settings_profile_repo 中下载的
  • pom_profile_repo 优先级高于 pom_repositories

# 最后确认 local_repo 本地仓库~/.m2/repository

这不算测试了,只是一个结论,可以任意测试。

  • 只要 ~/.m2/repository 中包含依赖,无论怎么配置,都会优先使用 local 本地仓库中的 jar.

# 最终结论

  • settings_mirror 的优先级高于 central
  • settings_profile_repo 优先级高于 settings_mirror
  • settings_profile_repo 优先级高于 pom_repositories
  • settings_profile_repo 优先级高于 pom_profile_repo
  • pom_profile_repo 优先级高于 pom_repositories
  • pom_repositories 优先级高于 settings_mirror

通过上面的比较得出完整的搜索链:

local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > settings_mirror > central

# 参考

  • https://blog.csdn.net/luanlouis/article/details/50492163
  • https://maven.org.cn/guides/index.html
  • https://my.oschina.net/polly/blog/2120650
#Maven
上次更新: 2024-08-19
Maven基础知识
Maven多模块配置

← Maven基础知识 Maven多模块配置→

最近更新
01
开始
01-09
02
AI工具分享
01-09
03
AI 导读
01-07
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Jason Huang | 闽ICP备2025088096号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式