Maven 基础
Maven 基础
Maven 简介
-
引出:
- 传统项目管理状态分析
- 会出现 jar 包不统一,jar 包不兼容的情况
- 工程升级维护过程操作频繁
- 传统项目管理状态分析
-
Maven 是什么
-
Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型 ( POM )
- POM ( Project Object Model ) 项目对象模型 ( 一个项目就是这么一个对象 )
-
Maven 通过加载 pom.xml 配置文件就可以知道项目信息了,
- Dependency 依赖管理,依赖管理与 POM 双向联系
- 依赖管理取自本地仓库,本地仓库取自私服,私服取自中央仓库
- Maven 构建生命周期 / 阶段 Build lifecycle & phases
-
Maven 核心:POM、Dependency、Build lifecycle & phases、插件
- 其他的是外围的、项目有关的
- 上面绿色部分为自己需要操作的
- 下面橙色部分为 Maven 已提供好的
-
-
Maven 的作用
- 项目构建:提供标准的、跨平台的自动化项目构建方式
- 依赖管理:方便快捷的管理项目依赖的资源 ( jar 包 ),避免资源间的版本冲突问题
- 统一开发结构:提供标准的、统一的项目结构
下载与安装
-
windows 版下载安装所需:上面的红框 ... bin.zip
- 下面的红框是源代码,可以不下
-
下载解压后:
-
bin:Maven 所有的可运行指令
-
其中的 mvn.cmd:( @REM 为注解,%JAVA_HOME%、%Maven_HOME% 皆为环境变量配置所需 )
-
记事本打开 mvn 内容与上述相似皆为配置检查等
-
-
boot:启动,里面有一个 jar 包作为类加载器
-
conf:配置管理
- logging:日志
- settings.xml:为核心配置
-
lib:Maven 运行所需的 jar 包
-
LICENSE 协议,NOTICE 注意,README 介绍 ......
-
-
类似 JAVA_HOME 在环境变量中新建添加 MAVEN_HOME、并在 Path 后添加
-
此时命令行输入 cmd 就会有显示,有显示而非错误指令就表示配置完成
Maven 基础概念
仓库
-
仓库:用于存储资源,包含各种 jar 包
- 几乎所有的 jar 包都在中央仓库 ( 由 Maven 开发团队管理,除了私有的非开源的之外 )
- 而我们所需要 jar 包时就是从中央仓库中下载下来到本地仓库中
- 而计算机、开发者有很多,而中央仓库又不在中国境内,所以访问会越来越多,信号也就越来越差,下载速度越慢,所以一般都是由计算机从公司私服中获取 ( 更快速 ),而私服依旧是从中央仓库拿取 ( 这样一旦私服中有过的,多个计算机访问获取就不需要再去中央下载了 )
-
仓库分类:
- 本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源
- 远程仓库:非本机电脑上的仓库,为本地仓库提供资源
- 中央仓库:Maven 团队维护,存储所有资源的仓库
- 私服:部门 / 公司范围内存储资源的仓库,从中央仓库获取资源
-
私服的作用:
-
保存具有版权的资源,包含购买或自主研发的 jar
- 中央仓库中的 jar 都是开源的,不能存储具有版权的资源
-
一定范围内共享资源,仅对内部开放,不对外共享
-
坐标
-
坐标:Maven 中的用于描述仓库中资源的位置
-
Maven 坐标主要组成:( pom.xml 中 jar 包代码标签 )
- groupld:定义当前 Maven 项目隶属组织名称 ( 通常是域名反写,例如: org.mybatis )
- artifactld:定义当前 Maven 项目名称 ( 通常是模块名称,例如 CRM、SMS )
- version:定义当前项目版本号
- packaging:定义该项目的打包方式 ( 非必须 )
-
Maven 坐标的作用
- 使用唯一标识,唯一性定位资源位置,通过该标识可以将资源的识别与下载工作交由机器完成
本地仓库
-
在 C 盘中打开用户文件夹,打开用户名对应的文件夹,命令行打开执行 mvn 后回车执行过后,就会在刚才的文件夹中出现 .m2 文件夹,这就是本地仓库
- 但随着日后的开发,通过 Maven 获取的 jar 包会越来越多,所以要自己更改本地仓库存储地址
-
查看、更改本地仓库位置
-
打开下载的 apache-maven 下载地址打开 conf 文件夹下的 settings.xml
-
更改本地仓库为:D:\maven\repository
-
-
在默认的 jar 的来源网址是国外的服务器,所以最好切换成阿里云的镜像
-
将阿里镜像代码粘贴到 settings.xml 中
<mirror> <!-- 识别 mirror 元素所用,唯一即可 --> <id>alimaven</id> <name>aliyun maven</name> <!-- 镜像 URL --> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <!-- 对哪种仓库进行镜像,简单来说就是替代哪个仓库,即:镜像的是中央仓库,若是访问中央仓库就从上述的 url 中拿 --> <mirrorOf>central</mirrorOf> </mirror>
-
-
全局 setting 与用户 setting 区别
- 全局 setting 定义了当前计算器中 Maven 的公共配置
- 用户 setting 定义了当前用户的配置
第一个 Maven 项目 ( 手工制作 )
Maven 工程目录结构
-
自定义 workspace 下整个打开的项目文件夹
- 项目文件夹下 src 文件夹、pom.xml
-
src 下有 main、test
- main 写程序
- test 写测试
-
main、test 下都有 java、resources
- java 写 java 语言程序
- resources 写配置文件
-
java 下都有 com,com 下公司名、项目名 ...
-
以上是 java 的目录结构,web 的目录结构在 main 下还多了一个 webapp 文件夹含有 WEB-INF
构建命令
-
命令行窗口输入 src 上一级目录名,如:
cd project-java
进入 project-java 目录- cls 清屏
-
dos 命令输入 ( 在 project-java 目录下执行 )
mvn compile # 编译 # 临最后显示 BUILD SUCCESS 即为下载准备工作完成 mvn clean # 清理 # 删除上述编译、在目录中下载添加的东西 mvn test # 测试 # 下载测试所需并测试 mvn package # 打包 # 只打包源程序放到仓库中,idea 不会打包 mvn install # 安装到本地仓库
- Maven 就是一个项目构建的过程
插件创建工程
-
不用上述手动创建目录,而是直接命令行输入生成模板样式:
第一个 Maven 项目 ( IDEA 生成 )
配置 Maven
- 详见另一篇文章:idea 配置 — 使用 Maven
手工创建 Java 项目
-
创建一个空的项目
- project structure、setting 配 SDK、Maven ( 同上述详见中做配置 )
- project structure 中的 Model 新建 Maven
- 右侧 Maven Projects 中 Lifecycle 为生命周期,Plugins 为插件
- 右上方绿色运行三角号左边下拉选择 Edit
- 加号新建,完成配置,可以自定义选择 compile 编译或者 clean 清理等,方便使用
- 这样在绿色左边的下拉中就可以直接找到
原型创建 Java 项目
- 新建时选择:
- 创建后 src 下 main 和 test 的 resources 需要自行创建
- 右键创建目录后,再右键 Mark Directory as 标记作为 ......
- 或者在 Project Structure 中的 Model 处添加
原型创建 Web 项目
-
新建或者 Model 中点击加号 New Model
- 都是在模板的基础上增补所需的规范文件夹
插件
-
tomcat 运行插件 ( 或者到上述的详见文章中下载使用 tomcat )
- 可到 https://mvnrepository.com 搜索 tomcat
<!--构建--> <build> <!-- 设置插件 --> <plugins> <!-- 具体的插件配置,此处的 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <!-- 进一步的配置,端口号+虚拟路径 --> <configuration> <port>80</port> <path>/</path> </configuration> </plugin> </plugins> </build>
- 这样在上述的绿色运行按钮左边的 Edit 里的 Command line 中就可以找到 tomcat 插件里的 run 运行操作,这样启动时下拉选好点击绿色按钮就可
-
pom.xml 解释
<!-- 指定pom的模型版本 --> <modelVersion>4.0.0</modelVersion> <!-- 组织id --> <groupId>org.example</groupId> <!-- 项目id --> <artifactId>pro23</artifactId> <!-- 打包方式,Web工程是war,Java工程是jar --> <packaging>war</packaging> <!-- 版本号,一般有两种,release完成版snapshot开发版 --> <version>1.0-SNAPSHOT</version> <!-- 设置当前工程的所有依赖 --> <dependencies> <!-- 具体的依赖 --> <dependency>
依赖管理
依赖配置
-
格式
<!-- 设置当前工程的所有依赖 --> <dependencies> <!-- 设置具体的依赖 --> <dependency> <!-- 依赖所需群组id --> <groupId>junit</groupId> <!-- 依赖所需项目id --> <artifactId>junit</artifactId> <!-- 依赖版本号 --> <version>4.13.2</version> </dependency> </dependencies>
依赖传递
-
若是项目一要用到项目二,这时就要把项目二当作资源写到项目一的依赖中,即一个项目开头红色方框框起来的部分
<dependencies> <!-- 设置具体的依赖 --> <dependency> <!-- 组织id --> <groupId>org.example</groupId> <!-- 项目id --> <artifactId>pro23</artifactId> <!-- 版本号,一般有两种,release完成版snapshot开发版 --> <version>1.0-SNAPSHOT</version> </dependency> ...... </dependencies>
-
通过这种方式,项目一也会拥有项目二的依赖
-
依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系,例如上面的项目一直接依赖项目二
- 间接依赖:当前项目间接依赖其他资源,即非直接的都是间接,例如上面的项目一间接依赖了项目二的直接依赖
-
依赖传递冲突问题
- 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
- 例如直接依赖的版本覆盖间接依赖的
- 声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
- 例如依赖的两个项目有各自的版本,就选顺序靠前的项目的依赖版本
- 特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的
- 例如一个项目中误写了两个不同版本的直接依赖,那就选先写的前面的
- 路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
可选依赖
-
可选依赖指对外隐藏当前所依赖的资源 —— 不透明
- 项目一看不到项目二的直接依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <!-- 隐藏依赖,不透明(默认是false) --> <optional>true</optional> </dependency> </dependencies>
排除依赖
- 排除依赖指主动断开依赖的资源,被排除的资源无需指定版本 —— 不需要
<dependeney>
<groupId>org.example</groupId>
<artifactId>pro23</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<!-- 写具体的要排除的 -->
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<!-- 不写版本号 -->
</exclusion>
</exclusions>
</dependency>
- 项目二主动在自己的依赖中写,让项目一无法用
依赖范围
-
依赖的 jar 默认情况可以在任何地方使用,可以通过 scope 标签设定其作用范围
-
作用范围
-
主程序范围有效 ( main 文件夹范围内 )
-
测试程序范围有效 ( test 文件夹范围内 )
-
是否参与打包 ( package 指令范围内 )
scope 主代码 测试代码 打包 范例 compile ( 默认 ) Y Y Y log4j test Y junit provided Y Y servlet-api runtime Y jdbc - compile —— 打出日志,哪都用得到
- test —— 测试用例,单元测试只在测试代码部分会用 ( test 目录下使用才有效 )
- provided —— 不能打包,servlet-api 版本不一致,要是冲突了会出大事
- runtime —— 只在最后打包的时候发布上就行,看似可有可无,但标准化来的话还是要配
-
-
在 idea 右侧的 Maven Project 中项目的 Dependencies 里 jar 包的后面加以括号标注范围
依赖范围传递性 ( 了解 )
-
带有依赖范围的资源在进行传递时,作用范围将受到影响
此行皆为直接依赖的 jar 包 compile test provided runtime 此列皆为间接依赖,引入的其他项目的依赖 ( 直接依赖与间接依赖的重复不同范围的 jar 包 ) compile compile test provided runtime test provided runtime runtime test provided runtime - 间接依赖中只有 compile 和 runtime 可以根据直接依赖的 jar 包的范围选择性显示
- 此表了解即可,主要还是看实际开发
生命周期与插件
构建生命周期
- Maven 构建生命周期描述的是一次构建过程经历了多少个事件
- Maven 对项目构建的生命周期划分为 3 套
- clean 生命周期:清理工作
- pre-clean 执行一些需要在 clean 之前完成的工作
- clean 移除所有上一次构建生成的文件
- post-clean 执行一些需要在 clean 之后立刻完成的工作
- default 生命周期:核心工作,例如编译、测试、打包、部署等
- ...... ( 包含很多,此处只举出好理解的 5 个 )
- compile
- test-compile
- test
- package
- install
- site 生命周期:产生报告,发布站点等
- pre-site 执行一些需要在生成站点文档之前完成的工作
- site 生成项目的站点文档
- post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
- site-deploy 将生成的站点文档部署到特定的服务器上
- clean 生命周期:清理工作
插件
-
插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能
- 即:通过插件在特定的生命周期做指定的事
-
默认 maven 在各个生命周期上绑定有预设的功能
-
通过插件可以自定义其他功能
-
例:
<build> <plugins> <plugin> <!-- 添加插件 --> <groupId>org. apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.2.1</version> <!-- 配置插件执行在什么时候 --> <executions> <execution> <!-- 执行位置,各插件不同,这里是指对源码打包 --> <goals> <goal>jar</goal> </goals> <!-- 执行的阶段(在生命周期中) --> <phase>generate-test-resources</phase> </execution> </executions> </plugin> </plugins> </build>
- 由于自行设置是在生命周期的 generate-test-resources 阶段执行,所以需要在右边 Maven Projects 里项目的 Lifecycle 生命周期里操作,先执行 clean 清除左侧 target,再执行 compile 就会显示 target,再执行 test 就会在 target 中多一个项目名开头的包,右键 Show In Explorer 就会打开文件目录,此包中就是项目的代码,即此包为源码包 ( 因为执行位置写的 jar ),
- 若是想给测试代码的源代码打包就是改 jar 为 test-jar
- 若是想都打包就写两个
<goal></goal>
,一个写 jar,一个写 test-jar
-
-
Maven 下载的官网中查看 Plugins 里是各种类型的插件,代码可以点击下方的 Examples 里的 Configuring Source Plugin 查看
-
添加后显示于该项目的 Plugins 中
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器