.neter 的 java 学习之路 - Maven(三)
1. 前奏
1.1 Maven是什么?
Maven 翻译为"专家"、"内行",是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目,现为由 Apache 软件基金会主持的独立 Apache 项目。
1.2 Maven 与 Nuget
作为一个.Neter Nuget肯定不陌生,Nuget加上Virtual Studio这个宇宙级的IDE加持,在易用性上简直不要太nice,刚开始用maven的时候真的是边用边骂,什么破玩意儿!!!一个包管理工具居然连搜索、安装这种简单的功能都没有。
一开始以为maven只是.net的Nuget一样,只是一个包管理工具,太年轻!
2. 正题
2.1 pom
POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
执行任务或目标时,Maven 会在当前目录中查找 POM。它读取 POM,获取所需的配置信息,然后执行目标。
2.2 lifecycle
Maven 构建生命周期定义了一个项目构建跟发布的过程:validate -> compile -> test -> package -> verify -> install -> deploy
验证 validate | 验证项目 | 验证项目是否正确且所有必须信息是可用的 |
---|---|---|
编译 compile | 执行编译 | 源代码编译在此阶段完成 |
测试 Test | 测试 | 使用适当的单元测试框架(例如JUnit)运行测试。 |
包装 package | 打包 | 创建JAR/WAR包如在 pom.xml 中定义提及的包 |
检查 verify | 检查 | 对集成测试的结果进行检查,以保证质量达标 |
安装 install | 安装 | 安装打包的项目到本地仓库,以供其他项目使用 |
部署 deploy | 部署 | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程 |
在执行maven命令的时候都会将当前阶段以及之前的阶段全部执行一次,执行mvn package,会将compile、Test也执行。
让我想到cicd工具中的stages,跟这个差不多。
2.3 dependency
maven的依赖有四个属性groupId(组id)、artifactId(项目id)、version(版本)、scope(范围)
2.3.1 scope
maven的依赖中的scope很有意思,以下scope的取值以及范围
scope取值 | 有效范围(compile, runtime, test) | 依赖传递 | 例子 |
---|---|---|---|
compile | all | 是 | spring-core |
provided | compile, test | 否 | servlet-api |
runtime | runtime, test | 是 | JDBC驱动 |
test | test | 否 | JUnit |
system | compile, test | 是 | |
maven构建的java项目在src下面都有一个main跟test的文件夹,main文件夹放源代码,test文件夹放单元测试;在进行打包的时候单元测试的代码是不会被打包到jar里面的,但是单元测试又需要像junit包的依赖,如果将junit打到jar中又会出现冗余,所以有了scope,scope为test的包只在test阶段生效。 | |||
scope还挺有意思。在.net的依赖里面就没有scope的概念,因为.net的单元测试都是在单独类库中。 |
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
2.3.2 exclusion
maven中依赖还有个很棒的东西:exclusion;任何可传递的依赖都可以通过 "exclusion" 元素被排除在外。举例说明,A 依赖 B, B 依赖 C,因此 A 可以标记 C 为 "被排除的"。
<!-- 引入zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
<!-- 与spring boot中的logback冲突直接去掉 -->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
如上,需要在spring boot中引用zookeeper的客户端,由于zk中引用了slf4j-log4j12跟spring boot中的logback出现冲突,可以通过排除一个解决冲突;
假如在.net中出现同样的情况,怎么办???
2.4 snapshot
在使用maven创建项目的时候,默认的项目id会加上一个SNAPSHOT的后缀,表示当前是一个快照版本,跟.net中的preview差不多。跟preview不同的是,.net中preview也是有版本的prev-1、prev-2需要手动修改,在maven快照版本会自动更新到最新的快照,还是个挺棒的设计。